//
//  Gogo DLL  basic defination unit.
//  programmed by M.yanagisawa.
//  this program is based on dgogo.zip - gogodll.pas.
//
//  Tab columns = 4
//
unit GogoDefs;

// 余計な定義は削除 & 自動変換の見にくいのを修正 @myan.
// ダイナミックロードに修正。

interface

uses
  Windows,Registry,SysUtils;

type
  MERET = Integer;
  MPARAM = LongInt;
  UPARAM = LongInt;

// ERROR CODES
const
  ME_NOERR				= 0;	// 正常終了
  ME_EMPTYSTREAM		= 1;	// ストリームが最後に達した
  ME_HALTED				= 2;	// (ユーザーの手により)中断された

  ME_INTERNALERROR		= 10;	// 内部エラー
  ME_PARAMERROR 		= 11;	// 設定でパラメーターエラー
  ME_NOFPU				= 12;	// FPUを装着していない!!
  ME_INFILE_NOFOUND		= 13;	// 入力ファイルを正しく開けない
  ME_OUTFILE_NOFOUND	= 14;	// 出力ファイルを正しく開けない
  ME_FREQERROR			= 15;	// 入出力周波数が正しくない
  ME_BITRATEERROR		= 16;	// 出力ビットレートが正しくない
  ME_WAVETYPE_ERR		= 17;	// ウェーブタイプが正しくない
  ME_CANNOT_SEEK		= 18;	// 正しくシーク出来ない
  ME_BITRATE_ERR		= 19;	// ビットレート設定が正しくない
  ME_BADMODEORLAYER		= 20;	// モード・レイヤの設定異常
  ME_NOMEMORY			= 21;	// メモリアローケーション失敗
  ME_CANNOT_SET_SCOPE	= 22;	// スレッド属性エラー(pthread only)
  ME_CANNOT_CREATE_THREAD = 23;	// スレッド生成エラー
  ME_WRITEERROR			= 24;	// 記憶媒体の容量不足

type
  MPGE_USERFUNC = function(Buf: Pointer; nLength: DWORD ):MERET; cdecl;
  TMpgeUserFunc = MPGE_USERFUNC;

////////////////////////////////////////////////////////////////////////////
/// 設定用
////////////////////////////////////////////////////////////////////////////
/// 入力ファイル設定 (※)
const

  MC_INPUTFILE			= 1;
/// para1 入力デバイスの選択
  MC_INPDEV_FILE		= 0; // 入力デバイスはファイル
  MC_INPDEV_STDIO		= 1; // 入力デバイスは標準入力
  MC_INPDEV_USERFUNC	= 2; // 入力デバイスはユーザー定義

/// para2 (必要であれば)ファイル名。ポインタを指定する
/// メモリよりエンコードの時は以下の構造体のポインタを指定する.
type
  MCP_INPDEV_USERFUNC = record
    pUserFunc: TMpgeUserFunc;
    nSize: DWORD;
    nBit: Integer;
    nFreq: Integer;
    nChn: Integer;
  end {MCP_INPDEV_USERFUNC};
  TMcpInpdevUserFunc = MCP_INPDEV_USERFUNC;
  PMcpInpdevUserFunc = ^MCP_INPDEV_USERFUNC;

const
  MC_INPDEV_MEMORY_NOSIZE = $FFFFFFFF; {(UINT_MAX);} // サイズ不定の時はこれをnSizeに入れる

////////////////////////////////////////////////////////////////////////////
/// 出力ファイル設定 (現在stdout未サポート) 
const
  MC_OUTPUTFILE		= 2;

/// para1 出力デバイス設定
  MC_OUTDEV_FILE	= 0; // 出力デバイスはファイル
  MC_OUTDEV_STDOUT	= 1; // 出力デバイスは標準出力
  MC_OUTDEV_USERFUNC = 2; // 出力デバイスはユーザー定義
/// para2 (必要であれば)ファイル名。ポインタ指定

////////////////////////////////////////////////////////////////////////////
/// エンコードタイプ
const
  MC_ENCODEMODE		= 3;
/// para1 モード設定
  MC_MODE_MONO		= 0; // モノラル
  MC_MODE_STEREO	= 1; // ステレオ
  MC_MODE_JOINT		= 2; // ジョイント
  MC_MODE_MSSTEREO	= 3; // ミッドサイド
  MC_MODE_DUALCHANNEL = 4; // デュアルチャネル

////////////////////////////////////////////////////////////////////////////
/// ビットレート設定
const
  MC_BITRATE		= 4;
/// para1 ビットレート 即値指定

////////////////////////////////////////////////////////////////////////////
/// 入力で用いるサンプル周波数の強制指定
const
  MC_INPFREQ		= 5;
/// para1 入出力で用いるデータ

////////////////////////////////////////////////////////////////////////////
/// 出力で用いるサンプル周波数の強制指定
const
  MC_OUTFREQ		= 6;
/// para1 入出力で用いるデータ

////////////////////////////////////////////////////////////////////////////
/// エンコード開始位置の強制指定(ヘッダを無視する時)
const
  MC_STARTOFFSET	=7;

////////////////////////////////////////////////////////////////////////////
/// 心理解析 ON/OFF
const
  MC_USEPSY			= 8;
/// PARA1 BOOL値(TRUE/FALSE)

////////////////////////////////////////////////////////////////////////////
/// 16KHz低帯域フィルタ ON/OFF
const
  MC_USELPF16		= 9;
/// PARA1 BOOL値(TRUE/FALSE)

////////////////////////////////////////////////////////////////////////////
/// ユニット指定 para1:BOOL値
const
  MC_USEMMX			= 10; // MMX機能の使用設定
  MC_USE3DNOW		= 11; // 3DNow!機能の使用設定
  MC_USEKNI			= 12; // KNI機能の使用設定
  MC_USEE3DNOW		= 13; // Extend 3D Now!機能の使用設定
  MC_USESPC1		= 14; // 特殊スイッチ使用設定
  MC_USESPC2		= 15; // 特殊スイッチ使用設定

////////////////////////////////////////////////////////////////////////////
/// ファイルタグ情報付加
const
  MC_ADDTAG			= 16;
/// dwPara1 タグ長
/// dwPara2 タグデータのポインタ

////////////////////////////////////////////////////////////////////////////
/// エンファシスタイプの設定
const
  MC_EMPHASIS		= 17;
/// para1 エンファシスタイプの設定
  MC_EMP_NONE		= 0; // エンファシスなし(dflt)
  MC_EMP_5015MS		= 1; // エンファシス50/15ms
  MC_EMP_CCITT		= 3; // エンファシスCCITT

////////////////////////////////////////////////////////////////////////////
/// VBRタイプの設定
const
  MC_VBR			= 18;

////////////////////////////////////////////////////////////////////////////
/// SMP support para1: interger
const
  MC_CPU			= 19;

////////////////////////////////////////////////////////////////////////////
/// 以下4つはRAW-PCMの設定のため
/// PCM入力時のlow, high bit 変換
const
  MC_BYTE_SWAP		= 20;

////////////////////////////////////////////////////////////////////////////
/// 8bit PCM 入力時
const
  MC_8BIT_PCM		= 21;

////////////////////////////////////////////////////////////////////////////
/// mono PCM 入力時
const
  MC_MONO_PCM		= 22;

////////////////////////////////////////////////////////////////////////////
/// Towns SND 入力時
const
  MC_TOWNS_SND		= 23;

///////////////////////////////////////////////////////////////////////////
// BeOS & Win32 Encode thread priority
const
  MC_THREAD_PRIORITY	= 24;
// (WIN32) dwPara1 MULTITHREAD Priority (THREAD_PRIORITY_**** at WinBASE.h )

///////////////////////////////////////////////////////////////////////////
// BeOS Read thread priority
//#if	defined(USE_BTHREAD)
const
	MC_READTHREAD_PRIORITY = 25;
//#endif

///////////////////////////////////////////////////////////////////////////
// output format 
const
	MC_OUTPUT_FORMAT	=	26;
// para1 
	MC_OUTPUT_NORMAL	= 	0;				// mp3+TAG(see MC_ADDTAG)
	MC_OUTPUT_RIFF_WAVE	=	1;				// RIFF/WAVE
	MC_OUTPUT_RIFF_RMP	=	2;				// RIFF/RMP

///////////////////////////////////////////////////////////////////////////
// LIST/INFO chunk of RIFF/WAVE or RIFF/RMP 
const
	MC_RIFF_INFO		=	27;
// para1 size of info(include info name)
// para2 pointer to info
//   offset            contents
//   0..3              info name
//   4..size of info-1 info

///////////////////////////////////////////////////////////////////////////
// verify and overwrite
const
	MC_VERIFY			= 	28;

///////////////////////////////////////////////////////////////////////////
// output directory
const
	MC_OUTPUTDIR		=	29;

///////////////////////////////////////////////////////////////////////////
// VBRの最低/最高ビットレートの設定
const
	MC_VBRBITRATE		=	30;
// para1 最低ビットレート (kbps)
// para2 最高ビットレート (kbps)

///////////////////////////////////////////////////////////////////////////
// 拡張フィルタの使用 LPF1, LPF2
const
	MC_ENHANCEDFILTER	=	31;
// para1 LPF1 (0-100)
// para2 LPF2 (0-100)

///////////////////////////////////////////////////////////////////////////
// Joint-stereoにおける、ステレオ/MSステレオの切り替えの閾値
const
	MC_MSTHRESHOLD	 	=	32;
// para1 threshold  (0-100)
// para2 mspower    (0-100)

///////////////////////////////////////////////////////////////////////////
// Language
const
	MC_LANG				=	33;

/////////////////////////////////////////////////////////////////////////////
/// 設定取得用
/////////////////////////////////////////////////////////////////////////////
/// 入力
const
  MG_INPUTFILE		= 1; // 入力ファイル名取得
  MG_OUTPUTFILE		= 2; // 出力ファイル名取得
  MG_ENCODEMODE		= 3; // エンコードモード
  MG_BITRATE		= 4; // ビットレート
  MG_INPFREQ		= 5; // 入力周波数
  MG_OUTFREQ		= 6; // 出力周波数
  MG_STARTOFFSET	= 7; // スタートオフセット(無視)
  MG_USEPSY			= 8; // 心理解析を使用する/しない
  MG_USEMMX			= 9; // MMX機能の使用設定
  MG_USE3DNOW		= 10; // 3DNow!機能の使用設定
  MG_USEKNI			= 11; // KNI機能の使用設定
  MG_USEE3DNOW		= 12; // Extend 3DNow!機能の使用設定
  MG_USESPC1		= 13; // 特殊スイッチ使用設定
  MG_USESPC2		= 14; // 特殊スイッチ使用設定
  MG_COUNT_FRAME	= 15; // 全体のフレーム数取得
  MG_MPEG_VERSION	= 17; //MPEG VERSION取得
  MG_READTHREAD_PRIORITY = 18; // thread priority to read for BeOS

////////////////////////////////////////////////////////////////////////////
/// MPGE_getUnitStates 用
const
  tFPU		= $00000001;
  tMMX		= $00000002;
  t3DN		= $00000004;
  tSSE		= $00000008;
  tCMOV		= $00000010;
  tE3DN		= $00000020;   // Athlon用(Externd 3D Now!)
  tEMMX		= $00000040;   // EMMX=E3DNow!_INT=SSE_INT

  tINTEL 	= $00000100;
  tAMD	 	= $00000200;
  tCYRIX	= $00000400;
  tIDT	 	= $00000800;
  tUNKNOWN	= $00008000; // ベンダー不明

  tSPC1		= $00010000;  // 特別なスイッチ
  tSPC2		= $00020000;  // 用途は決まってない

  tFAMILY4	= $00100000;  // 486 この時ベンダー判定は当てにならない
  tFAMILY5	= $00200000;  // 586 (P5, P5-MMX, K6, K6-2, K6-III)
  tFAMILY6	= $00400000;  // 686以降 P-Pro, P-II, P-III, Athlon

type
  FMPGE_MERRETreturnedonly = function:MERET  ;cdecl;
  FMPGE_setConfigure = function (mode: MPARAM; dwPara1: UPARAM; dwPara2: UPARAM): MERET  ;cdecl;
  FMPGE_getConfigure = function (mode: MPARAM; var para1): MERET  ;cdecl;
  FMPGE_getUnitStates = function (var units: LongInt): MERET  ;cdecl;
  FMPGE_getVersion = function (var vercode: LongInt; verstring: PChar): MERET; cdecl;
/// vercode = 0x125 -> version 1.25
/// verstring -> "ver 1.25 1999/09/25" 等(260byte以上の領域を用意すること)

// GogoDLL Apis
var
  MPGE_initializeWork : FMPGE_MERRETreturnedonly;
  MPGE_setConfigure : FMPGE_setConfigure;
  MPGE_getConfigure : FMPGE_getConfigure;
  MPGE_detectConfigure: FMPGE_MERRETreturnedonly;
  MPGE_processFrame: FMPGE_MERRETreturnedonly;
  MPGE_closeCoder: FMPGE_MERRETreturnedonly;
  MPGE_endCoder: FMPGE_MERRETreturnedonly;
  MPGE_getUnitStates : FMPGE_getUnitStates;
  MPGE_getVersion : FMPGE_getVersion;
//
  GogoDLLPath : string;

function InitGogoDefs:boolean;
procedure DeallocateGogoDLL;

implementation

var
  hDLLHandle : THandle;
  DLLOpenCnt : integer;	// DLL参照カウンタ

function InitGogoDefs:boolean;
var
  s : string;
  Reg : TRegistry;
begin
  Result:=FALSE;
  if DLLOpenCnt>0 then begin
    inc(DLLOpenCnt);	// 参照カウンタ+1
    Result:=TRUE;
    exit;
  end;
  GogoDLLPath:='';
  s:='';
  hDLLHandle:=LoadLibrary('GOGO.DLL');
  if hDLLHandle=0 then begin
    // registryの指す場所。
    Reg:=TRegistry.Create;
    try
      with Reg do begin
        RootKey:= HKEY_CURRENT_USER;
        if OpenKey('Software\MarineCat\GOGO_DLL',FALSE) then begin
          s:=ReadString('INSTPATH');
          CloseKey;
        end;
      end;
    Finally
      Reg.Free;
    end;
    if s<>'' then hDLLHandle:=LoadLibrary(PChar(s));
  end;
  if hDLLHandle<>0 then begin
    @MPGE_initializeWork:=GetProcAddress(hDLLHandle,'MPGE_initializeWork');
    @MPGE_setConfigure:=GetProcAddress(hDLLHandle,'MPGE_setConfigure');
    @MPGE_getConfigure:=GetProcAddress(hDLLHandle,'MPGE_getConfigure');
    @MPGE_detectConfigure:=GetProcAddress(hDLLHandle,'MPGE_detectConfigure');
    @MPGE_processFrame:=GetProcAddress(hDLLHandle,'MPGE_processFrame');
    @MPGE_closeCoder:=GetProcAddress(hDLLHandle,'MPGE_closeCoder');
    @MPGE_endCoder:=GetProcAddress(hDLLHandle,'MPGE_endCoder');
    @MPGE_getUnitStates:=GetProcAddress(hDLLHandle,'MPGE_getUnitStates');
    @MPGE_getVersion:=GetProcAddress(hDLLHandle,'MPGE_getVersion');
    if (@MPGE_initializeWork=NIL)
      or (@MPGE_setConfigure=NIL)
      or (@MPGE_getConfigure=NIL)
      or (@MPGE_detectConfigure=NIL)
      or (@MPGE_processFrame=NIL)
      or (@MPGE_closeCoder=NIL)
      or (@MPGE_endCoder=NIL)
      or (@MPGE_getUnitStates=NIL)
      or (@MPGE_getVersion=NIL) then begin
	  FreeLibrary(hDLLHandle);
	  DLLOpenCnt:=0;
	  hDLLHandle:=0;
    end
    else begin
      DLLOpenCnt:=1;
      GogoDLLPath:=s;
      Result:=TRUE; // 正常終了
	end;
  end;
end;

procedure DeallocateGogoDLL;
  begin
    if DLLOpenCnt=1 then begin
      if hDLLHandle<>0 then FreeLibrary(hDLLHandle);
      hDLLHandle:=0;
    end;
    dec(DLLOpenCnt);
  end;

initialization
  hDLLHandle:=0;
  DLLOpenCnt:=0;

finalization
  // 一応、後始末
  DLLOpenCnt:=1; // 開いていたら必ずDeAllocate
  DeallocateGogoDLL;

end.
