Help with FFI - another try

Eugene Beschastnov eugene.beschastnov at gmail.com
Mon Jul 17 06:27:01 UTC 2006


Hi all!

(It looks like my previous message was not properly delivered. Here is
another try.)

Can anybody help me with FFI? I'm trying to use LAME Mp3 Encoder DLL
3.96.1 (lame_enc.dll), but Squeak always crashes.

Here is part of header file of DLL (whole header file,
BladeMP3EncDLL.h, is attached):
=== Start of BladeMP3EncDLL.h =====================================
 #define ATTRIBUTE_PACKED
 #pragma pack(push)
#pragma pack(1)

typedef struct  {
    DWORD   dwConfig;           // BE_CONFIG_XXXXX
                                // Currently only BE_CONFIG_MP3 is supported
    union   {

        struct  {

            DWORD   dwSampleRate;       // 48000, 44100 and 32000 allowed
              BYTE    byMode;         // BE_MP3_MODE_STEREO,
BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
              WORD    wBitrate;       // 32, 40, 48, 56, 64, 80, 96,
112, 128, 160, 192, 224, 256 and 320 allowed
            BOOL    bPrivate;
            BOOL    bCRC;
            BOOL    bCopyright;
            BOOL    bOriginal;

              } mp3;                  // BE_CONFIG_MP3

            struct
              {
            // STRUCTURE INFORMATION
              DWORD           dwStructVersion;
            DWORD           dwStructSize;

              // BASIC ENCODER SETTINGS
            DWORD           dwSampleRate;       // SAMPLERATE OF INPUT FILE
            DWORD           dwReSampleRate;     // DOWNSAMPLERATE,
0=ENCODER DECIDES
              LONG            nMode;              //
BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
            DWORD           dwBitrate;          // CBR bitrate, VBR min bitrate
            DWORD           dwMaxBitrate;       // CBR ignored, VBR Max bitrate
              LONG            nPreset;            // Quality preset,
use one of the settings of the LAME_QUALITY_PRESET enum
            DWORD           dwMpegVersion;      // FUTURE USE, MPEG-1 OR MPEG-2
            DWORD           dwPsyModel;         // FUTURE USE, SET TO 0
              DWORD           dwEmphasis;         // FUTURE USE, SET TO 0

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

            // VBR STUFF
            BOOL            bWriteVBRHeader;    // WRITE XING VBR
HEADER (TRUE/FALSE)
            BOOL            bEnableVBR;         // USE VBR ENCODING (TRUE/FALSE)
              INT             nVBRQuality;        // VBR QUALITY 0..9
            DWORD           dwVbrAbr_bps;       // Use ABR in stead of
nVBRQuality
            VBRMETHOD       nVbrMethod;
            BOOL            bNoRes;             // Disable Bit
resorvoir (TRUE/FALSE)

            // MISC SETTINGS
              BOOL            bStrictIso;         // Use strict ISO
encoding rules (TRUE/FALSE)
            WORD            nQuality;           // Quality Setting,
HIGH BYTE should be NOT LOW byte, otherwhise quality=5

            // FUTURE USE, SET TO 0, align strucutre to 331 bytes
              BYTE            btReserved[255-4*sizeof(DWORD) - sizeof( WORD )];

              } LHV1;                 // LAME header version 1

        struct  {

            DWORD   dwSampleRate;
            BYTE    byMode;
            WORD    wBitrate;
            BYTE    byEncodingMethod;

        } aac;

      } format;

} BE_CONFIG, *PBE_CONFIG ATTRIBUTE_PACKED;

__declspec(dllexport) BE_ERR    beInitStream(PBE_CONFIG pbeConfig,
PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream);

#pragma pack(pop)
=== End of BladeMP3EncDLL.h ======================================


Here is what I wrote to correspond DLL header (part of fileout, whole
fileout is attached as LameTest.st). Default values are from
Example.cpp (also attached), which works correct:
=== Start of LameTest.st ===========================================
 ExternalStructure subclass: #BeConfig
    instanceVariableNames: ''
     classVariableNames: ''
    poolDictionaries: ''
    category: 'LameTest'!

!BeConfig methodsFor: 'initialization' stamp: 'epb 6/21/2006 20:36'!
 initialize
    super initialize.
     self
        dwConfig: 256 "BE_CONFIG_LAME";
         format: BeConfigFormat new.! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

BeConfig class
    instanceVariableNames: ''!

!BeConfig class methodsFor: 'as yet unclassified' stamp: 'epb 6/20/2006 21:46'!
 fields
    "self defineFields"
     ^#(
        (dwConfig    'long' "BE_CONFIG_XXXXX. BE_CONFIG_MP3 = 0,
BE_CONFIG_LAME = 256")
         (format      'BeConfigFormat')
    )
 ! !


ExternalStructure subclass: #BeConfigFormat
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'LameTest'!

!BeConfigFormat methodsFor: 'initialization' stamp: 'epb 6/21/2006 20:38'!
 initialize
    super initialize.
     self lhv1: BeConfigLvh1 new.! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

BeConfigFormat class
     instanceVariableNames: ''!

!BeConfigFormat class methodsFor: 'as yet unclassified' stamp: 'epb
6/20/2006 21:44'!
fields
    "self defineFields"
     ^#(
        (lhv1    'BeConfigLvh1')
     )
! !


 ExternalStructure subclass: #BeConfigLvh1
    instanceVariableNames: ''
     classVariableNames: ''
    poolDictionaries: ''
     category: 'LameTest'!

!BeConfigLvh1 methodsFor: 'initialization' stamp: 'epb 6/22/2006 14:37'!
initialize
    super initialize.
     self
        dwStructVersion: 1;
         dwStructSize: 333;
        dwReSampleRate: 0;
        setBeMp3ModeJStereo;
        dwBitrate: 128  "sizeof(beConfig)";
        setPresetR3Mix;
        setMpeg1;
        dwPsyModel: 0;
         dwEmphasis: 0;
        bOriginal: 1;
         bWriteVBRHeader: 1! !


!BeConfigLvh1 methodsFor: 'set parameters' stamp: 'epb 6/21/2006 20:53'!
 setBeMp3ModeJStereo
     self nMode: 1! !

!BeConfigLvh1 methodsFor: 'lame quality presets' stamp: 'epb 6/21/2006 20:57'!
 setPresetR3Mix
    self nPreset: 4! !

 !BeConfigLvh1 methodsFor: 'mpeg version' stamp: 'epb 6/21/2006 21:03'!
setMpeg1
     self dwMpegVersion: 1! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

BeConfigLvh1 class
    instanceVariableNames: ''!

!BeConfigLvh1 class methodsFor: 'as yet unclassified' stamp: 'epb
6/22/2006 14:36'!
 fields
    "self defineFields"
     ^#(
        "STRUCTURE INFORMATION"
        (dwStructVersion     'long')
        (dwStructSize         'long')

         "BASIC ENCODER SETTINGS"
        (dwSampleRate         'long' "SAMPLERATE OF INPUT FILE")
         (dwReSampleRate    'long' "DOWNSAMPLERATE, 0=ENCODER DECIDES")
        (nMode                'long'  "BE_MP3_MODE_STEREO,
BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO")
        (dwBitrate            'long'  "CBR bitrate, VBR min bitrate")
         (dwMaxBitrate        'long'  "CBR ignored, VBR Max bitrate")
        (nPreset                'long'  "Quality preset, use one of
the settings of the LAME_QUALITY_PRESET enum")
        (dwMpegVersion        'long'  "FUTURE USE, MPEG-1 OR MPEG-2")
         (dwPsyModel        'long'  "FUTURE USE, SET TO 0")
        (dwEmphasis        'long'  "FUTURE USE, SET TO 0")

        "BIT STREAM SETTINGS"
         (bPrivate            'long'  "Set Private Bit (TRUE/FALSE)")
        (bCRC                'long'  "Insert CRC (TRUE/FALSE)")
        (bCopyright            'long'  "Set Copyright Bit (TRUE/FALSE)")
         (bOriginal            'long'  "Set Original Bit (TRUE/FALSE)")

         "VBR STUFF"
        (bWriteVBRHeader    'long'  "WRITE XING VBR HEADER (TRUE/FALSE)")
         (bEnableVBR        'long'  "USE VBR ENCODING (TRUE/FALSE)")
        (nVBRQuality        'long'  "VBR QUALITY 0..9")
        (dwVbrAbrBps        'long'  "Use ABR in stead of nVBRQuality")
         (nVbrMethod        'long'  "VBR_METHOD_NONE = -1,
VBR_METHOD_DEFAULT =  0, VBR_METHOD_OLD =  1, VBR_METHOD_NEW =  2,
VBR_METHOD_MTRH =  3, VBR_METHOD_ABR =  4")

        (bNoRes                'long'  "Disable Bit resorvoir (TRUE/FALSE)")

         "MISC SETTINGS"
        (bStrictIso            'long'  "Use strict ISO encoding rules
(TRUE/FALSE)")
        (nQuality            'long'  "Quality Setting, HIGH BYTE
should be NOT LOW byte, otherwhise quality=5")

        "FUTURE USE, SET TO 0, align strucutre to 331 bytes"
         (btReserved            'byte' 237  "[255-4*sizeof(DWORD) -
sizeof( WORD )]")
)! !


Object subclass: #LameEncoder
     instanceVariableNames: ''
    classVariableNames: ''
     poolDictionaries: ''
    category: 'LameTest'!

 "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

 LameEncoder class
    instanceVariableNames: ''!

 !LameEncoder class methodsFor: 'api' stamp: 'epb 6/21/2006 21:50'!
apiBeInitStreamBeConfig: beConfig dwSamples: dwSamples dwMp3Buffer:
dwMp3Buffer hbeStream: hbeStream
    <apicall: ulong 'beInitStream' ( BeConfig* long* long* ulong* )
module: 'lame_enc.dll'>
     ^self externalCallFailed! !


 !LameEncoder class methodsFor: 'unit-tests' stamp: 'epb 6/29/2006 15:54'!
testInitStream
 | beConfig errCode dwSamples dwMp3Buffer hbeStream |
beConfig := BeConfig new
     sampleRate: 44100;
    yourself.

 dwSamples := WordArray new: 0.
dwMp3Buffer := WordArray new: 0.
 hbeStream := WordArray new: 0.

errCode := LameEncoder apiBeInitStreamBeConfig: beConfig dwSamples:
dwSamples dwMp3Buffer: dwMp3Buffer hbeStream: hbeStream.

Transcript
    show: 'errCode: '; show: errCode; cr;
    show: 'dwSamples: '; show: dwSamples first; cr;
    show: 'dwMp3Buffer: '; show: dwMp3Buffer first; cr;
    show: 'hbeStream: '; show: hbeStream first; cr.! !
=== End of LameTest.st ===========================================


When I'm executing "LameEncoder testInitStream", Squeak crashes.

Here is stack dump:
=== Start of stack dump ===========================================
---------------------------------------------------------------------
  Fri Jul 14 14:39:58 2006

Exception code: C0000005
  Exception addr: 00427325
Access violation (read access) at 00000480
  EAX:00000480    EBX:88AA1235    ECX:115381B8    EDX:00000481
ESI:00000000    EDI:00520580    EBP:00520580    ESP:0006FB74
  EIP:00427325    EFL:00010282
FP Control: FFFF027F
  FP Status:  FFFF4861
FP Tag:     FFFFFFFF
VM Version: Squeak  3.7.1 (release) from Sep 23 2004
Compiler: gcc 2.95.2 19991024 (release)

  Current byte code: 209
Primitive index: 70

  Loaded plugins:
    lame_enc.dll
      SqueakFFIPrims 23 September 2004 (e)
    LargeIntegers v1.3 23 September 2004 (i)
      Matrix2x3Plugin 23 September 2004 (i)
    FloatArrayPlugin 23 September 2004 (i)
      B2DPlugin 23 September 2004 (i)
    BitBltPlugin 23 September 2004 (i)
      SecurityPlugin 23 September 2004 (i)
    FilePlugin 23 September 2004 (i)
      MiscPrimitivePlugin 23 September 2004 (i)


Stack dump:
=== End of stack dump ===========================================


I tried to call this DLL by many ways, but without success. The best I
did is asking DLL about it's version (beVersion).

Can anybody help?

-- 
Eugene
-------------- next part --------------
A non-text attachment was scrubbed...
Name: BladeMP3EncDLL.h
Type: application/octet-stream
Size: 7656 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20060717/e18392a3/BladeMP3EncDLL.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: LameTest.st
Type: application/octet-stream
Size: 17778 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20060717/e18392a3/LameTest.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Example.cpp
Type: application/octet-stream
Size: 7923 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20060717/e18392a3/Example.obj


More information about the Squeak-dev mailing list