![]() | |
![]() |
| | Thread Tools | Search this Thread | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
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(AsioDelta 1010); 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. } |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
| |