Solved

Using Lame_enc.dll In Delphi

Posted on 2004-08-28
5
3,847 Views
Last Modified: 2012-06-27
Does anyone know where I can download API info on this DLL please?

Basically, I'm after details on how to call this dll from Delphi (5) rather than calling lame.exe - which although works fine, doesn't give the calling program any data on the current encoding progress.

Thanks...

TDK_Man
0
Comment
Question by:tdk_man
  • 3
5 Comments
 
LVL 13

Expert Comment

by:BlackTigerX
ID: 11921713
maybe a TLameCoder component would help?

http://www.inspired.sk/delphi/components/download.php?ID=29
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 11923208
Google to the resque: http://www.google.nl/search?num=100&q=Lame_enc.dll+delphi

This chinese page http://it.icxo.com/htmlnews/2004/08/05/285745.htm is partly in english and has some interesting comments. But http://lame.sourceforge.net/ could be more useful, though. You can download the full sourcecode there and all you have to do then is convert the header files to Delphi. A helluvajob but it is possible.

One warning: Using the LAME encoding engine (or other mp3 encoding technology) in your software may require a patent license in some countries.
0
 
LVL 1

Author Comment

by:tdk_man
ID: 11925580
Alex

Thanks for the Google link, but when I click on it, they all appear as visited links because I actually spent many hours on Google over two days without luck before posting on here.

If you check out the links, (and I appreciate that you personally would have had no reason to), you would find that none of them actually tell you anything. In particular, none give you a list of API calls and many are asking the same questions I am.

It's odd, but according to a few of the web sites I've visited, whoever created the dll didn't publish the API calls for it.

I've checked out the chinese site though. Very interesting, so thanks for that. Unfortunately, It looks like the dll will not encode at 128 (min 160)! If this is true, it makes it worse than what I'm using at the moment - the lame.exe program.

I have the source to the dll already, but I don't have the skills to modify and recompile it.

BlackTigerX:

Have got that file - thanks. Will check it out and report back.

TDK_Man

0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 200 total points
ID: 11929477
Actually, if you have the source, you have an overview of the API too. ;-)
Unfortunately, since the source is written in C++ you'd have to convert it from C++ to Delphi. I don't think the people of JEDI have started on this yet so if there's no link with a Delphi version of the API, there's no other option than writing it yourself. And if you don't know C++, it would be quite difficult. (But basically, you'd have to focus on the *.H files mostly.) You don't have to recompile the source or even modify it. You just have to be able to read the source and determine which functions you need to call.

I've downloaded the latest version of the source of LAME from http://lame.sourceforge.net/ and I noticed it has a little textfile called "API" which provides a bit of information about the API. Also, it seems to me that all you need to convert to Delphi is the "Lame.h" file. I searched a bit further in the source and guess what? It's your lucky day, I hope... It has a PAS file in the \lame-3.96.1\Dll folder! They have created a Delphi unit for you already. I'll paste it here, although this is for the latest version only:

unit MP3export;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  //type definitions
  //typedef            unsigned long                  HBE_STREAM;
  //typedef            HBE_STREAM                        *PHBE_STREAM;
  //typedef            unsigned long                  BE_ERR;
  THBE_STREAM = LongWord;
  PHBE_STREAM = ^PHBE_STREAM;
  BE_ERR = LongWord;

const
  // encoding formats
  //#define            BE_CONFIG_MP3                  0
  //#define            BE_CONFIG_LAME                  256
  BE_CONFIG_MP3 = 0;
  BE_CONFIG_LAME = 256;

  // error codes
  //#define    BE_ERR_SUCCESSFUL                    0x00000000
  //#define    BE_ERR_INVALID_FORMAT            0x00000001
  //#define    BE_ERR_INVALID_FORMAT_PARAMETERS      0x00000002
  //#define    BE_ERR_NO_MORE_HANDLES            0x00000003
  //#define    BE_ERR_INVALID_HANDLE            0x00000004
  BE_ERR_SUCCESSFUL: LongWord = 0;
  BE_ERR_INVALID_FORMAT: LongWord = 1;
  BE_ERR_INVALID_FORMAT_PARAMETERS: LongWord = 2;
  BE_ERR_NO_MORE_HANDLES: LongWord = 3;
  BE_ERR_INVALID_HANDLE: LongWord = 4;

  // other constants

  BE_MAX_HOMEPAGE = 256;

  // format specific variables

  BE_MP3_MODE_STEREO = 0;
  BE_MP3_MODE_DUALCHANNEL = 2;
  BE_MP3_MODE_MONO = 3;

type

  TMP3 = packed record
    dwSampleRate: LongWord;
    byMode: Byte;
    wBitRate: Word;
    bPrivate: LongWord;
    bCRC: LongWord;
    bCopyright: LongWord;
    bOriginal: LongWord;
  end;

  TLHV1 = packed record
    // STRUCTURE INFORMATION
    dwStructVersion: DWORD;
    dwStructSize: DWORD;

    // BASIC ENCODER SETTINGS
    dwSampleRate: DWORD; // ALLOWED SAMPLERATE VALUES DEPENDS ON dwMPEGVersion
    dwReSampleRate: DWORD; // DOWNSAMPLERATE, 0=ENCODER DECIDES
    nMode: Integer; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
    dwBitrate: DWORD; // CBR bitrate, VBR min bitrate
    dwMaxBitrate: DWORD; // CBR ignored, VBR Max bitrate
    nQuality: Integer; // Quality setting (NORMAL,HIGH,LOW,VOICE)
    dwMpegVersion: DWORD; // MPEG-1 OR MPEG-2
    dwPsyModel: DWORD; // FUTURE USE, SET TO 0
    dwEmphasis: DWORD; // FUTURE USE, SET TO 0

    // BIT STREAM SETTINGS
    bPrivate: LONGBOOL; // Set Private Bit (TRUE/FALSE)
    bCRC: LONGBOOL; // Insert CRC (TRUE/FALSE)
    bCopyright: LONGBOOL; // Set Copyright Bit (TRUE/FALSE)
    bOriginal: LONGBOOL; // Set Original Bit (TRUE/FALSE_

    // VBR STUFF
    bWriteVBRHeader: LONGBOOL; // WRITE XING VBR HEADER (TRUE/FALSE)
    bEnableVBR: LONGBOOL; // USE VBR ENCODING (TRUE/FALSE)
    nVBRQuality: Integer; // VBR QUALITY 0..9

    btReserved: array[ 0..255 ] of Byte; // FUTURE USE, SET TO 0
  end;

  TAAC = packed record
    dwSampleRate: LongWord;
    byMode: Byte;
    wBitRate: Word;
    byEncodingMethod: Byte;
  end;

  TFormat = packed record
    case byte of
      1: ( mp3: TMP3 );
      2: ( lhv1: TLHV1 );
      3: ( aac: TAAC );
  end;

  TBE_Config = packed record
    dwConfig: LongWord;
    format: TFormat;
  end;

  PBE_Config = ^TBE_Config;

  //typedef struct      {
  //      // BladeEnc DLL Version number
  //
  //      BYTE      byDLLMajorVersion;
  //      BYTE      byDLLMinorVersion;
  //
  //      // BladeEnc Engine Version Number
  //
  //      BYTE      byMajorVersion;
  //      BYTE      byMinorVersion;
  //
  //      // DLL Release date
  //
  //      BYTE      byDay;
  //      BYTE      byMonth;
  //      WORD      wYear;
  //
  //      // BladeEnc      Homepage URL
  //
  //      CHAR      zHomepage[BE_MAX_HOMEPAGE + 1];
  //
  //} BE_VERSION, *PBE_VERSION;

  TBE_Version = record
    byDLLMajorVersion: Byte;
    byDLLMinorVersion: Byte;

    byMajorVersion: Byte;
    byMinorVersion: Byte;

    byDay: Byte;
    byMonth: Byte;
    wYear: Word;

    zHomePage: array[ 0..BE_MAX_HOMEPAGE + 1 ] of Char;
  end;

  PBE_Version = ^TBE_Version;

  //__declspec(dllexport) BE_ERR      beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream);
  //__declspec(dllexport) BE_ERR      beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput);
  //__declspec(dllexport) BE_ERR      beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput);
  //__declspec(dllexport) BE_ERR      beCloseStream(HBE_STREAM hbeStream);
  //__declspec(dllexport) VOID      beVersion(PBE_VERSION pbeVersion);

  {
  Function beInitStream(var pbeConfig: TBE_CONFIG; var dwSample: LongWord; var dwBufferSize: LongWord; var phbeStream: THBE_STREAM ): BE_Err; cdecl; external 'Bladeenc.dll';
  //Function beEncodeChunk(hbeStream: THBE_STREAM; nSamples: LongWord; pSample: PSmallInt;pOutput: PByte; var pdwOutput: LongWord): BE_Err; cdecl; external 'Bladeenc.dll';
  Function beEncodeChunk(hbeStream: THBE_STREAM; nSamples: LongWord; var pSample;var pOutput; var pdwOutput: LongWord): BE_Err; stdcall; cdecl 'Bladeenc.dll';
  Function beDeinitStream(hbeStream: THBE_STREAM; var pOutput; var pdwOutput: LongWord): BE_Err; cdecl; external 'Bladeenc.dll';
  Function beCloseStream(hbeStream: THBE_STREAM): BE_Err; cdecl; external 'Bladeenc.dll';
  Procedure beVersion(var pbeVersion: TBE_VERSION); cdecl; external 'Bladeenc.dll';
  }

function beInitStream( var pbeConfig: TBE_CONFIG; var dwSample: LongWord; var dwBufferSize: LongWord; var phbeStream: THBE_STREAM ): BE_Err; cdecl; external 'Lame_enc.dll';
//Function beEncodeChunk(hbeStream: THBE_STREAM; nSamples: LongWord; pSample: PSmallInt;pOutput: PByte; var pdwOutput: LongWord): BE_Err; cdecl; external 'Lame_enc.dll';
function beEncodeChunk( hbeStream: THBE_STREAM; nSamples: LongWord; var pSample; var pOutput; var pdwOutput: LongWord ): BE_Err; cdecl; external 'Lame_enc.dll';
function beDeinitStream( hbeStream: THBE_STREAM; var pOutput; var pdwOutput: LongWord ): BE_Err; cdecl; external 'Lame_enc.dll';
function beCloseStream( hbeStream: THBE_STREAM ): BE_Err; cdecl; external 'Lame_enc.dll';
procedure beVersion( var pbeVersion: TBE_VERSION ); cdecl; external 'Lame_enc.dll';

procedure EncodeWavToMP3( fs, fd: Integer );
implementation

uses InternetSnd, TraiteWav;

{----------------------------------------}

procedure EncodeWavToMP3( fs, fd: Integer );
var
  err: Integer;
  beConfig: TBE_Config;
  dwSamples, dwSamplesMP3: LongWord;
  hbeStream: THBE_STREAM;
  error: BE_ERR;
  pBuffer: PSmallInt;
  pMP3Buffer: PByte;
  Marque: PChar;

  done: LongWord;
  dwWrite: LongWord;
  ToRead: LongWord;
  ToWrite: LongWord;
  i: Integer;

begin
  beConfig.dwConfig := BE_CONFIG_LAME;

  {
    beConfig.Format.mp3.dwSampleRate := WavInfo.SamplesPerSec;
    beConfig.Format.mp3.byMode := BE_MP3_MODE_STEREO;
    beConfig.Format.mp3.wBitrate := strToInt(MainFrm.Mp3BitRate.Text);
    beConfig.Format.mp3.bCopyright := 0;
    beConfig.Format.mp3.bCRC := $00000000;
    beConfig.Format.mp3.bOriginal := 0;
    beConfig.Format.mp3.bPrivate := 0;
  }
  //Structure information
  beConfig.Format.lhv1.dwStructVersion := 1;
  beConfig.Format.lhv1.dwStructSize := SizeOf( beConfig );
  //Basic encoder setting
  beConfig.Format.lhv1.dwSampleRate := WavInfo.SamplesPerSec;
  beConfig.Format.lhv1.dwReSampleRate := 44100;
  beConfig.Format.lhv1.nMode := BE_MP3_MODE_STEREO;
  beConfig.Format.lhv1.dwBitrate := strToInt( MainFrm.Mp3BitRate.Text );
  beConfig.Format.lhv1.dwMaxBitrate := strToInt( MainFrm.Mp3BitRate.Text );
  beConfig.Format.lhv1.nQuality := 2;
  beConfig.Format.lhv1.dwMPegVersion := 1; //MPEG1
  beConfig.Format.lhv1.dwPsyModel := 0;
  beConfig.Format.lhv1.dwEmphasis := 0;
  //Bit Stream Settings
  beConfig.Format.lhv1.bPrivate := False;
  beConfig.Format.lhv1.bCRC := False;
  beConfig.Format.lhv1.bCopyright := True;
  beConfig.Format.lhv1.bOriginal := True;
  //VBR Stuff
  beConfig.Format.lhv1.bWriteVBRHeader := false;
  beConfig.Format.lhv1.bEnableVBR := false;
  beConfig.Format.lhv1.nVBRQuality := 0;

  i := 0;
  error := beInitStream( beConfig, dwSamples, dwSamplesMP3, hbeStream );
  if error = BE_ERR_SUCCESSFUL then begin
    pBuffer := AllocMem( dwSamples * 2 );
    pMP3Buffer := AllocMem( dwSamplesMP3 );
    try
      done := 0;

      error := FileSeek( fs, 0, 0 );
      while ( done < TotalSize ) do begin
        if ( done + dwSamples * 2 < TotalSize ) then
          ToRead := dwSamples * 2
        else begin
          ToRead := TotalSize - done;
          //FillChar(buf[0],dwSamples*2,0);
          FillChar( pbuffer^, dwSamples, 0 );
        end;

        //if FileRead(fs, buf[0], toread) = -1
        if FileRead( fs, pbuffer^, toread ) = -1 then raise Exception.Create( 'Erreur de lecture' );

        //error := beEncodeChunk(hbeStream, toRead div 2, Buf[0], TmpBuf[0], toWrite);
        error := beEncodeChunk( hbeStream, toRead div 2, pBuffer^, pMP3Buffer^, toWrite );

        if error <> BE_ERR_SUCCESSFUL then begin
          beCloseStream( hbeStream );
          raise Exception.Create( 'Echec de l''encodage' );
        end;

        //if FileWrite(fd, TmpBuf[0], toWrite) = -1
        if FileWrite( fd, pMP3Buffer^, toWrite ) = -1 then raise Exception.Create( 'Erreur d''écriture' );

        done := done + toread;
        inc( i );
        if i mod 64 = 0 then begin
          MainFrm.ProgressBar1.Position := round( 100 * done / Totalsize );
          Application.ProcessMessages;
        end;
      end;

      error := beDeInitStream( hbeStream, pMP3Buffer^, dwWrite );
      //error := beDeInitStream(hbeStream, TmpBuf[0], dwWrite);

      if error <> BE_ERR_SUCCESSFUL then begin
        beCloseStream( hbeStream );
        raise Exception.Create( 'Echec à la sortie' );
      end;

      if dwWrite <> 0 then begin
        //if FileWrite(fd, TmpBuf[0], dwWrite) = -1
        if FileWrite( fd, pMP3Buffer^, dwWrite ) = -1 then raise Exception.Create( 'Erreur à la dernière écriture' );
      end;

      beCloseStream( hbeStream );
    finally
      FreeMem( pBuffer );
      FreeMem( pMP3Buffer );
    end;
  end
  else begin

  end;
end;

end.

-------------------------------------------
Too bad the error messages are in french. ;-)
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12004540
Is your problem solved now?
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now