Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / June 2007

Tip: Looking for answers? Try searching our database.

Help converting C++ interface declare to c#

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jeff M - 06 Jun 2007 21:48 GMT
I would greatly appreciate anyone that can help me with the proper way to
declare this interface?

Here is the C++ declaration:

interface IASIO : public IUnknown
{
    virtual ASIOBool init(void *sysHandle) = 0;
    virtual void getDriverName(char *name) = 0;   
    virtual long getDriverVersion() = 0;
    virtual void getErrorMessage(char *string) = 0;   
    virtual ASIOError start() = 0;
    virtual ASIOError stop() = 0;
    virtual ASIOError getChannels(long *numInputChannels, long
*numOutputChannels) = 0;
    virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;
    virtual ASIOError getBufferSize(long *minSize, long *maxSize,
        long *preferredSize, long *granularity) = 0;
    virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;
    virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;
    virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;
    virtual ASIOError getClockSources(ASIOClockSource *clocks /* array */, long
*numSources) = 0;
    virtual ASIOError setClockSource(long reference) = 0;
    virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp
*tStamp) = 0;
    virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;
    virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long
numChannels,
        long bufferSize, ASIOCallbacks *callbacks) = 0;
    virtual ASIOError disposeBuffers() = 0;
    virtual ASIOError controlPanel() = 0;
    virtual ASIOError future(long selector,void *opt) = 0;
    virtual ASIOError outputReady() = 0;
};

Here is what I have so far:

 [Guid("615C2C61-F8EB-11d3-B0B2-0000E8ED4AD9")]
   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   public interface IAsioDelta1010
   {
       AsioBool init(IntPtr sysHandle);        // void *
       void getDriverName(out String name);    // char *
       int getDriverVersion();
       void getErrorMessage(out String message);   // char *
       AsioError start();
       AsioError stop();
       AsioError getChannels(out int numInputChannels, out int
numOutputChannels);//  long *
       AsioError getLatencies(out int inputLatency, out int outputLatency);
//  long *
       AsioError getBufferSize(out int minSize, out int maxSize,
                               out int preferredSize, out int granularity);
  // long *
       AsioError canSampleRate(double sampleRate);
       AsioError getSampleRate(out double sampleRate); // double *
       AsioError setSampleRate(double sampleRate);
       AsioError getClockSources(ref AsioClockSource[] clocks, ref int
numSources);
       AsioError setClockSource(int reference);
       AsioError getSamplePosition(out AsioSamples sPos, out AsioTimeStamp
tStamp);
       AsioError getChannelInfo(ref AsioChannelInfo info);
       AsioError createBuffers(ref AsioBufferInfo[] bufferInfos, int
numChannels,
                               int bufferSize, ref AsioCallbacks callbacks);
       AsioError disposeBuffers();
       AsioError controlPanel();
       AsioError future(int selector, IntPtr opt); // void *
       AsioError outputReady();
   }

Here is my code to create the COM object:

Type AsioDelta1010 = Type.GetTypeFromCLSID(AsioGuid.Delta1010, true);
IAsioDelta1010 delta1010 =
(IAsioDelta1010)Activator.CreateInstance(AsioDelta1010);
delta1010.init(this.Handle); <<<--- this throws protected memory access
violation
int ver = delta1010.getDriverVersion();
Console.WriteLine(ver);

Here is the rest of the code I have converted thus far:

   public enum AsioBool : int
   {
       ASIOFalse = 0,
       ASIOTrue = 1
   }

   public enum AsioError : int
   {
       ASE_OK = 0,             // This value will be returned whenever the
call succeeded
       ASE_SUCCESS = 0x3f4847a0,    // unique success return value for ASIOFuture
calls
       ASE_NotPresent = -1000, // hardware input or output is not present or
available
       ASE_HWMalfunction,      // hardware is malfunctioning (can be returned
by any ASIO function)
       ASE_InvalidParameter,   // input parameter invalid
       ASE_InvalidMode,        // hardware is in a bad mode or used in a bad
mode
       ASE_SPNotAdvancing,     // hardware is not running when sample position
is inquired
       ASE_NoClock,            // sample clock or rate cannot be determined or
is not present
       ASE_NoMemory            // not enough memory for completing the request
   }

   public struct AsioClockSource
   {
       public int index;                    // as used for ASIOSetClockSource()
       public int associatedChannel;        // for instance, S/PDIF or AES/EBU
       public int associatedGroup;           // see channel groups
(ASIOGetChannelInfo())
       public AsioBool isCurrentSource;    // ASIOTrue if this is the current
clock source
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
       public string name;                   // for user selection
   }

   public struct AsioSamples
   {
        public uint hi;
       public uint lo;
    }

   public struct AsioTimeStamp
   {
       public uint hi;
       public uint lo;
   }

   public enum AsioSampleType : int
   {
       ASIOSTInt16MSB   = 0,
       ASIOSTInt24MSB   = 1,        // used for 20 bits as well
       ASIOSTInt32MSB   = 2,
       ASIOSTFloat32MSB = 3,        // IEEE 754 32 bit float
       ASIOSTFloat64MSB = 4,        // IEEE 754 64 bit double float
       // these are used for 32 bit data buffer, with different alignment of
the data inside
       // 32 bit PCI bus systems can be more easily used with these
       ASIOSTInt32MSB16 = 8,        // 32 bit data with 16 bit alignment
       ASIOSTInt32MSB18 = 9,        // 32 bit data with 18 bit alignment
       ASIOSTInt32MSB20 = 10,        // 32 bit data with 20 bit alignment
       ASIOSTInt32MSB24 = 11,        // 32 bit data with 24 bit alignment
       ASIOSTInt16LSB   = 16,
       ASIOSTInt24LSB   = 17,        // used for 20 bits as well
       ASIOSTInt32LSB   = 18,
       ASIOSTFloat32LSB = 19,        // IEEE 754 32 bit float, as found on Intel x86
architecture
       ASIOSTFloat64LSB = 20,         // IEEE 754 64 bit double float, as found on
Intel x86 architecture
       // these are used for 32 bit data buffer, with different alignment of
the data inside
       // 32 bit PCI bus systems can more easily used with these
       ASIOSTInt32LSB16 = 24,        // 32 bit data with 18 bit alignment
       ASIOSTInt32LSB18 = 25,        // 32 bit data with 18 bit alignment
       ASIOSTInt32LSB20 = 26,        // 32 bit data with 20 bit alignment
       ASIOSTInt32LSB24 = 27,        // 32 bit data with 24 bit alignment
       //    ASIO DSD format.
       ASIOSTDSDInt8LSB1   = 32,        // DSD 1 bit data, 8 samples per byte. First
sample in Least significant bit.
       ASIOSTDSDInt8MSB1   = 33,        // DSD 1 bit data, 8 samples per byte. First
sample in Most significant bit.
       ASIOSTDSDInt8NER8    = 40,        // DSD 8 bit data, 1 sample per byte. No
Endianness required.
       ASIOSTLastEntry
   }

   public struct AsioChannelInfo
   {
       public int channel;            // on input, channel index
       public AsioBool isInput;        // on input
       public AsioBool isActive;        // on exit
       public int channelGroup;        // dto
       public AsioSampleType type;    // dto
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
       public string name;                   // dto
   }

   public struct AsioBufferInfo
   {
       public AsioBool isInput;            // on input:  ASIOTrue: input, else output
       public int channelNum;            // on input:  channel index
       public IntPtr buffers1;            // on output: double buffer addresses
       public IntPtr buffers2;            // on output: double buffer addresses
   }

   public enum AsioTimeInfoFlags: uint
   {
       kSystemTimeValid        = 1,            // must always be valid
       kSamplePositionValid    = 1 << 1,       // must always be valid
       kSampleRateValid        = 1 << 2,
       kSpeedValid             = 1 << 3,
       kSampleRateChanged      = 1 << 4,
       kClockSourceChanged     = 1 << 5
   }

   public struct AsioTimeInfo
   {
       public double          speed;                  // absolute speed (1. =
nominal)
       public AsioTimeStamp systemTime;             // system time related
to samplePosition, in nanoseconds
                                               // on mac, must be derived from
Microseconds() (not UpTime()!)
                                               // on windows, must be derived
from timeGetTime()
       public AsioSamples samplePosition;
       public double sampleRate;             // current rate
       public uint flags;                    // (see below)
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=12)]
       public string reserved;                   // for user selection
   }

   public enum AsioTimeCodeFlags : uint
   {
       kTcValid                = 1,
       kTcRunning              = 1 << 1,
       kTcReverse              = 1 << 2,
       kTcOnspeed              = 1 << 3,
       kTcStill                = 1 << 4,
       kTcSpeedValid           = 1 << 8
   }

   public struct AsioTimeCode
   {      
       public double          speed;               // speed relation (fraction
of nominal speed)
                                                   // optional; set to 0. or
1. if not supported
       public AsioSamples timeCodeSamples;     // time in samples
       public uint flags;                          // some information flags
(see below)
       [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
       public string future;                       //
   }

   public struct AsioTime                  // both input/output
   {
       public int reserved1;               // must be 0
       public int reserved2;               // must be 0
       public int reserved3;               // must be 0
       public int reserved4;               // must be 0
       public AsioTimeInfo timeInfo;       // required
       public AsioTimeCode timeCode;       // optional, evaluated if
(timeCode.flags & kTcValid)
   }

   public enum AsioMessageSelectors: int
   {
       kAsioSelectorSupported = 1,    // selector in <value>, returns 1L if
supported,
                                   // 0 otherwise
       kAsioEngineVersion,            // returns engine (host) asio implementation
version,
                                   // 2 or higher
       kAsioResetRequest,            // request driver reset. if accepted, this
                                   // will close the driver (ASIO_Exit() ) and
                                   // re-open it again (ASIO_Init() etc). some
                                   // drivers need to reconfigure for instance
                                   // when the sample rate changes, or some basic
                                   // changes have been made in ASIO_ControlPanel().
                                   // returns 1L; note the request is merely passed
                                   // to the application, there is no way to determine
                                   // if it gets accepted at this time (but it usually
                                   // will be).
       kAsioBufferSizeChange,        // not yet supported, will currently always
return 0L.
                                   // for now, use kAsioResetRequest instead.
                                   // once implemented, the new buffer size is expected
                                   // in <value>, and on success returns 1L
       kAsioResyncRequest,            // the driver went out of sync, such that
                                   // the timestamp is no longer valid. this
                                   // is a request to re-start the engine and
                                   // slave devices (sequencer). returns 1 for ok,
                                   // 0 if not supported.
       kAsioLatenciesChanged,         // the drivers latencies have changed. The
engine
                                   // will refetch the latencies.
       kAsioSupportsTimeInfo,        // if host returns true here, it will expect the
                                   // callback bufferSwitchTimeInfo to be called instead
                                   // of bufferSwitch
       kAsioSupportsTimeCode,        //
       kAsioMMCCommand,            // unused - value: number of commands, message
points to mmc commands
       kAsioSupportsInputMonitor,    // kAsioSupportsXXX return 1 if host
supports this
       kAsioSupportsInputGain,     // unused and undefined
       kAsioSupportsInputMeter,    // unused and undefined
       kAsioSupportsOutputGain,    // unused and undefined
       kAsioSupportsOutputMeter,   // unused and undefined
       kAsioOverload,              // driver detected an overload
       kAsioNumMessageSelectors
   }

   public delegate void AsioBufferSwitchDelegate(int doubleBufferIndex,
AsioBool directProcess);
   public delegate void AsioSampleRateDidChangeDelegate(double sRate);
   public delegate void AsioMessageDelegate(int selector, int value, IntPtr
message, ref double opt);
   public delegate AsioTime AsioBufferSwitchTimeInfoDelegate(ref AsioTime
times, int doubleBufferIndex, AsioBool directProcess);

   public struct AsioCallbacks
   {
       public AsioBufferSwitchDelegate BufferSwitch;
       //void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess);
        // bufferSwitch indicates that both input and output are to be processed.
        // the current buffer half index (0 for A, 1 for B) determines
        // - the output buffer that the host should start to fill. the other buffer
        //   will be passed to output hardware regardless of whether it got filled
        //   in time or not.
        // - the input buffer that is now filled with incoming data. Note that
        //   because of the synchronicity of i/o, the input always has at
        //   least one buffer latency in relation to the output.
        // directProcess suggests to the host whether it should immedeately
        // start processing (directProcess == ASIOTrue), or whether its process
        // should be deferred because the call comes from a very low level
        // (for instance, a high level priority interrupt), and direct processing
        // would cause timing instabilities for the rest of the system. If in doubt,
        // directProcess should be set to ASIOFalse.
        // Note: bufferSwitch may be called at interrupt time for highest
efficiency.

       public AsioSampleRateDidChangeDelegate SampleRateDidChange;
       //void (*sampleRateDidChange) (ASIOSampleRate sRate);
        // gets called when the AudioStreamIO detects a sample rate change
        // If sample rate is unknown, 0 is passed (for instance, clock loss
        // when externally synchronized).

       public AsioMessageDelegate Message;
       //long (*asioMessage) (long selector, long value, void* message,
double* opt);
        // generic callback for various purposes, see selectors below.
        // note this is only present if the asio version is 2 or higher

       public AsioBufferSwitchTimeInfoDelegate BufferSwitchTimeInfo;
       //ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long
doubleBufferIndex, ASIOBool directProcess);
        // new callback with time info. makes ASIOGetSamplePosition() and various
        // calls to ASIOGetSampleRate obsolete,
        // and allows for timecode sync etc. to be preferred; will be used if
        // the driver calls asioMessage with selector kAsioSupportsTimeInfo.
   }
Ben Voigt [C++ MVP] - 09 Jun 2007 18:22 GMT
>I would greatly appreciate anyone that can help me with the proper way to
> declare this interface?
[quoted text clipped - 81 lines]
> delta1010.init(this.Handle); <<<--- this throws protected memory access
> violation

what is "this.Handle"?  Is this code inside a Windows.Forms object?

You will need to refer to the documentation for the component, a "sysHandle"
is almost certainly entirely different from an "HWND".

> int ver = delta1010.getDriverVersion();
> Console.WriteLine(ver);
[quoted text clipped - 276 lines]
> // the driver calls asioMessage with selector kAsioSupportsTimeInfo.
>    }

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.