| 
							- /*
 -  * Copyright (C) 2006 Robert Reif
 -  * Portions copyright (C) 2007 Ralf Beck
 -  * Portions copyright (C) 2007 Johnny Petrantoni
 -  * Portions copyright (C) 2007 Stephane Letz
 -  * Portions copyright (C) 2008 William Steidtmann
 -  * Portions copyright (C) 2010 Peter L Jones
 -  * Portions copyright (C) 2010 Torben Hohn
 -  * Portions copyright (C) 2010 Nedko Arnaudov
 -  * Portions copyright (C) 2010 Joakim Hernberg
 -  *
 -  * This library is free software; you can redistribute it and/or
 -  * modify it under the terms of the GNU Lesser General Public
 -  * License as published by the Free Software Foundation; either
 -  * version 2.1 of the License, or (at your option) any later version.
 -  *
 -  * This library is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -  * Lesser General Public License for more details.
 -  *
 -  * You should have received a copy of the GNU Lesser General Public
 -  * License along with this library; if not, write to the Free Software
 -  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 -  */
 - 
 - /*
 -  *  Todo (maybe):
 -  *  create a freely distributable asio.h replacement
 -  *  add ASIOOutputReady() support
 -  */
 - 
 - #include <stdio.h>
 - #include <errno.h>
 - #include <unistd.h>
 - #include <sys/mman.h>
 - #include <pthread.h>
 - 
 - #include "wine/debug.h"
 - #include "objbase.h"
 - #include "mmsystem.h"
 - #include "winreg.h"
 - #include "wine/unicode.h"
 - 
 - #include <jack/jack.h>
 - #include <jack/thread.h>
 - 
 - #define IEEE754_64FLOAT 1
 - #include "asio.h"
 - 
 - WINE_DEFAULT_DEBUG_CHANNEL(asio);
 - 
 - #define MAX_ENVIRONMENT_SIZE        6
 - #define ASIO_MAX_NAME_LENGTH        32
 - #define ASIO_MINIMUM_BUFFERSIZE     16
 - #define ASIO_MAXIMUM_BUFFERSIZE     8192
 - #define ASIO_PREFERRED_BUFFERSIZE   1024
 - 
 - /* ASIO drivers (breaking the COM specification) use the Microsoft variety of
 -  * thiscall calling convention which gcc is unable to produce.  These macros
 -  * add an extra layer to fixup the registers. Borrowed from config.h and the
 -  * wine source code.
 -  */
 - 
 - /* From config.h */
 - #define __ASM_DEFINE_FUNC(name,suffix,code) asm(".text\n\t.align 4\n\t.globl " #name suffix "\n\t.type " #name suffix ",@function\n" #name suffix ":\n\t.cfi_startproc\n\t" code "\n\t.cfi_endproc\n\t.previous");
 - #define __ASM_GLOBAL_FUNC(name,code) __ASM_DEFINE_FUNC(name,"",code)
 - #define __ASM_NAME(name) name
 - #define __ASM_STDCALL(args) ""
 - 
 - /* From wine source */
 - #ifdef __i386__  /* thiscall functions are i386-specific */
 - 
 - #define THISCALL(func) __thiscall_ ## func
 - #define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func)
 - #define __thiscall __stdcall
 - #define DEFINE_THISCALL_WRAPPER(func,args) \
 -     extern void THISCALL(func)(void); \
 -     __ASM_GLOBAL_FUNC(__thiscall_ ## func, \
 -                       "popl %eax\n\t" \
 -                       "pushl %ecx\n\t" \
 -                       "pushl %eax\n\t" \
 -                       "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
 - #else /* __i386__ */
 - 
 - #define THISCALL(func) func
 - #define THISCALL_NAME(func) __ASM_NAME(#func)
 - #define __thiscall __cdecl
 - #define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
 - 
 - #endif /* __i386__ */
 - 
 - /* Hide ELF symbols for the COM members - No need to to export them */
 - #define HIDDEN __attribute__ ((visibility("hidden")))
 - 
 - /*****************************************************************************
 -  * IWineAsio interface
 -  */
 - 
 - #define INTERFACE IWineASIO
 - DECLARE_INTERFACE_(IWineASIO,IUnknown)
 - {
 -     STDMETHOD_(HRESULT, QueryInterface)         (THIS_ IID riid, void** ppvObject) PURE;
 -     STDMETHOD_(ULONG, AddRef)                   (THIS) PURE;
 -     STDMETHOD_(ULONG, Release)                  (THIS) PURE;
 -     STDMETHOD_(ASIOBool, Init)                  (THIS_ void *sysRef) PURE;
 -     STDMETHOD_(void, GetDriverName)             (THIS_ char *name) PURE;
 -     STDMETHOD_(LONG, GetDriverVersion)          (THIS) PURE;
 -     STDMETHOD_(void, GetErrorMessage)           (THIS_ char *string) PURE;
 -     STDMETHOD_(ASIOError, Start)                (THIS) PURE;
 -     STDMETHOD_(ASIOError, Stop)                 (THIS) PURE;
 -     STDMETHOD_(ASIOError, GetChannels)          (THIS_ LONG *numInputChannels, LONG *numOutputChannels) PURE;
 -     STDMETHOD_(ASIOError, GetLatencies)         (THIS_ LONG *inputLatency, LONG *outputLatency) PURE;
 -     STDMETHOD_(ASIOError, GetBufferSize)        (THIS_ LONG *minSize, LONG *maxSize, LONG *preferredSize, LONG *granularity) PURE;
 -     STDMETHOD_(ASIOError, CanSampleRate)        (THIS_ ASIOSampleRate sampleRate) PURE;
 -     STDMETHOD_(ASIOError, GetSampleRate)        (THIS_ ASIOSampleRate *sampleRate) PURE;
 -     STDMETHOD_(ASIOError, SetSampleRate)        (THIS_ ASIOSampleRate sampleRate) PURE;
 -     STDMETHOD_(ASIOError, GetClockSources)      (THIS_ ASIOClockSource *clocks, LONG *numSources) PURE;
 -     STDMETHOD_(ASIOError, SetClockSource)       (THIS_ LONG index) PURE;
 -     STDMETHOD_(ASIOError, GetSamplePosition)    (THIS_ ASIOSamples *sPos, ASIOTimeStamp *tStamp) PURE;
 -     STDMETHOD_(ASIOError, GetChannelInfo)       (THIS_ ASIOChannelInfo *info) PURE;
 -     STDMETHOD_(ASIOError, CreateBuffers)        (THIS_ ASIOBufferInfo *bufferInfo, LONG numChannels, LONG bufferSize, ASIOCallbacks *asioCallbacks) PURE;
 -     STDMETHOD_(ASIOError, DisposeBuffers)       (THIS) PURE;
 -     STDMETHOD_(ASIOError, ControlPanel)         (THIS) PURE;
 -     STDMETHOD_(ASIOError, Future)               (THIS_ LONG selector,void *opt) PURE;
 -     STDMETHOD_(ASIOError, OutputReady)          (THIS) PURE;
 - };
 - #undef INTERFACE
 - 
 - typedef struct IWineASIO *LPWINEASIO;
 - 
 - typedef struct IOChannel
 - {
 -     ASIOBool                    active;
 -     jack_default_audio_sample_t *audio_buffer;
 -     char                        port_name[ASIO_MAX_NAME_LENGTH];
 -     jack_port_t                 *port;
 - } IOChannel;
 - 
 - typedef struct IWineASIOImpl
 - {
 -     /* COM stuff */
 -     const IWineASIOVtbl         *lpVtbl;
 -     LONG                        ref;
 - 
 -     /* The app's main window handle on windows, 0 on OS/X */
 -     HWND                        sys_ref;
 - 
 -     /* ASIO stuff */
 -     LONG                        asio_active_inputs;
 -     LONG                        asio_active_outputs;
 -     BOOL                        asio_buffer_index;
 -     ASIOCallbacks               *asio_callbacks;
 -     BOOL                        asio_can_time_code;
 -     LONG                        asio_current_buffersize;
 -     INT                         asio_driver_state;
 -     ASIOSamples                 asio_sample_position;
 -     ASIOSampleRate              asio_sample_rate;
 -     ASIOTime                    asio_time;
 -     BOOL                        asio_time_info_mode;
 -     ASIOTimeStamp               asio_time_stamp;
 -     LONG                        asio_version;
 - 
 -     /* WineASIO configuration options */
 -     LONG                        wineasio_number_inputs;
 -     LONG                        wineasio_number_outputs;
 -     BOOL                        wineasio_autostart_server;
 -     BOOL                        wineasio_connect_to_hardware;
 -     LONG                        wineasio_fixed_buffersize;
 -     LONG                        wineasio_preferred_buffersize;
 - 
 -     /* JACK stuff */
 -     jack_client_t               *jack_client;
 -     char                        jack_client_name[ASIO_MAX_NAME_LENGTH];
 -     int                         jack_num_input_ports;
 -     int                         jack_num_output_ports;
 -     const char                  **jack_input_ports;
 -     const char                  **jack_output_ports;
 - 
 -     /* process callback buffers */
 -     jack_default_audio_sample_t *callback_audio_buffer;
 -     IOChannel                   *input_channel;
 -     IOChannel                   *output_channel;
 - } IWineASIOImpl;
 - 
 - enum { Loaded, Initialized, Prepared, Running };
 - 
 - /****************************************************************************
 -  *  Interface Methods
 -  */
 - 
 - /*
 -  *  as seen from the WineASIO source
 -  */
 - 
 - HIDDEN HRESULT   STDMETHODCALLTYPE      QueryInterface(LPWINEASIO iface, REFIID riid, void **ppvObject);
 - HIDDEN ULONG     STDMETHODCALLTYPE      AddRef(LPWINEASIO iface);
 - HIDDEN ULONG     STDMETHODCALLTYPE      Release(LPWINEASIO iface);
 - HIDDEN ASIOBool  STDMETHODCALLTYPE      Init(LPWINEASIO iface, void *sysRef);
 - HIDDEN void      STDMETHODCALLTYPE      GetDriverName(LPWINEASIO iface, char *name);
 - HIDDEN LONG      STDMETHODCALLTYPE      GetDriverVersion(LPWINEASIO iface);
 - HIDDEN void      STDMETHODCALLTYPE      GetErrorMessage(LPWINEASIO iface, char *string);
 - HIDDEN ASIOError STDMETHODCALLTYPE      Start(LPWINEASIO iface);
 - HIDDEN ASIOError STDMETHODCALLTYPE      Stop(LPWINEASIO iface);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetChannels (LPWINEASIO iface, LONG *numInputChannels, LONG *numOutputChannels);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetLatencies(LPWINEASIO iface, LONG *inputLatency, LONG *outputLatency);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetBufferSize(LPWINEASIO iface, LONG *minSize, LONG *maxSize, LONG *preferredSize, LONG *granularity);
 - HIDDEN ASIOError STDMETHODCALLTYPE      CanSampleRate(LPWINEASIO iface, ASIOSampleRate sampleRate);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetSampleRate(LPWINEASIO iface, ASIOSampleRate *sampleRate);
 - HIDDEN ASIOError STDMETHODCALLTYPE      SetSampleRate(LPWINEASIO iface, ASIOSampleRate sampleRate);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetClockSources(LPWINEASIO iface, ASIOClockSource *clocks, LONG *numSources);
 - HIDDEN ASIOError STDMETHODCALLTYPE      SetClockSource(LPWINEASIO iface, LONG index);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetSamplePosition(LPWINEASIO iface, ASIOSamples *sPos, ASIOTimeStamp *tStamp);
 - HIDDEN ASIOError STDMETHODCALLTYPE      GetChannelInfo(LPWINEASIO iface, ASIOChannelInfo *info);
 - HIDDEN ASIOError STDMETHODCALLTYPE      CreateBuffers(LPWINEASIO iface, ASIOBufferInfo *bufferInfo, LONG numChannels, LONG bufferSize, ASIOCallbacks *asioCallbacks);
 - HIDDEN ASIOError STDMETHODCALLTYPE      DisposeBuffers(LPWINEASIO iface);
 - HIDDEN ASIOError STDMETHODCALLTYPE      ControlPanel(LPWINEASIO iface);
 - HIDDEN ASIOError STDMETHODCALLTYPE      Future(LPWINEASIO iface, LONG selector, void *opt);
 - HIDDEN ASIOError STDMETHODCALLTYPE      OutputReady(LPWINEASIO iface);
 - 
 - /*
 -  * thiscall wrappers for the vtbl (as seen from app side 32bit)
 -  */
 - 
 - HIDDEN void __thiscall_Init(void);
 - HIDDEN void __thiscall_GetDriverName(void);
 - HIDDEN void __thiscall_GetDriverVersion(void);
 - HIDDEN void __thiscall_GetErrorMessage(void);
 - HIDDEN void __thiscall_Start(void);
 - HIDDEN void __thiscall_Stop(void);
 - HIDDEN void __thiscall_GetChannels(void);
 - HIDDEN void __thiscall_GetLatencies(void);
 - HIDDEN void __thiscall_GetBufferSize(void);
 - HIDDEN void __thiscall_CanSampleRate(void);
 - HIDDEN void __thiscall_GetSampleRate(void);
 - HIDDEN void __thiscall_SetSampleRate(void);
 - HIDDEN void __thiscall_GetClockSources(void);
 - HIDDEN void __thiscall_SetClockSource(void);
 - HIDDEN void __thiscall_GetSamplePosition(void);
 - HIDDEN void __thiscall_GetChannelInfo(void);
 - HIDDEN void __thiscall_CreateBuffers(void);
 - HIDDEN void __thiscall_DisposeBuffers(void);
 - HIDDEN void __thiscall_ControlPanel(void);
 - HIDDEN void __thiscall_Future(void);
 - HIDDEN void __thiscall_OutputReady(void);
 - 
 - /*
 -  *  Jack callbacks
 -  */
 - 
 - static int  bufsize_callback (jack_nframes_t nframes, void *arg);
 - static int  process_callback (jack_nframes_t nframes, void *arg);
 - static int  srate_callback (jack_nframes_t nframes, void *arg);
 - 
 - /*
 -  *  Support functions
 -  */
 - 
 - HRESULT WINAPI  WineASIOCreateInstance(REFIID riid, LPVOID *ppobj);
 - static  BOOL    configure_driver(IWineASIOImpl *This);
 - 
 - #ifdef __WINESRC__
 - static DWORD WINAPI jack_thread_creator_helper(LPVOID arg);
 - static int          jack_thread_creator(pthread_t* thread_id, const pthread_attr_t* attr, void *(*function)(void*), void* arg);
 - #endif
 - 
 - /* {48D0C522-BFCC-45cc-8B84-17F25F33E6E8} */
 - static GUID const CLSID_WineASIO = {
 - 0x48d0c522, 0xbfcc, 0x45cc, { 0x8b, 0x84, 0x17, 0xf2, 0x5f, 0x33, 0xe6, 0xe8 } };
 - 
 - static const IWineASIOVtbl WineASIO_Vtbl =
 - {
 -     (void *) QueryInterface,
 -     (void *) AddRef,
 -     (void *) Release,
 - 
 -     (void *) THISCALL(Init),
 -     (void *) THISCALL(GetDriverName),
 -     (void *) THISCALL(GetDriverVersion),
 -     (void *) THISCALL(GetErrorMessage),
 -     (void *) THISCALL(Start),
 -     (void *) THISCALL(Stop),
 -     (void *) THISCALL(GetChannels),
 -     (void *) THISCALL(GetLatencies),
 -     (void *) THISCALL(GetBufferSize),
 -     (void *) THISCALL(CanSampleRate),
 -     (void *) THISCALL(GetSampleRate),
 -     (void *) THISCALL(SetSampleRate),
 -     (void *) THISCALL(GetClockSources),
 -     (void *) THISCALL(SetClockSource),
 -     (void *) THISCALL(GetSamplePosition),
 -     (void *) THISCALL(GetChannelInfo),
 -     (void *) THISCALL(CreateBuffers),
 -     (void *) THISCALL(DisposeBuffers),
 -     (void *) THISCALL(ControlPanel),
 -     (void *) THISCALL(Future),
 -     (void *) THISCALL(OutputReady)
 - };
 - 
 - #ifdef __WINESRC__
 - /* structure needed to create the JACK callback thread in the wine process context */
 - struct {
 -     void        *(*jack_callback_thread) (void*);
 -     void        *arg;
 -     pthread_t   jack_callback_pthread_id;
 -     HANDLE      jack_callback_thread_created;
 - } jack_thread_creator_privates;
 - #endif
 - 
 - /*****************************************************************************
 -  * Interface method definitions
 -  */
 - 
 - 
 - HIDDEN HRESULT STDMETHODCALLTYPE QueryInterface(LPWINEASIO iface, REFIID riid, void **ppvObject)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl *)iface;
 - 
 -     TRACE("iface: %p, riid: %s, ppvObject: %p)\n", iface, debugstr_guid(riid), ppvObject);
 - 
 -     if (ppvObject == NULL)
 -         return E_INVALIDARG;
 - 
 -     if (IsEqualIID(&CLSID_WineASIO, riid))
 -     {
 -         AddRef(iface);
 -         *ppvObject = This;
 -         return S_OK;
 -     }
 - 
 -     return E_NOINTERFACE;
 - }
 - 
 - /*
 -  * ULONG STDMETHODCALLTYPE AddRef(LPWINEASIO iface);
 -  * Function: Increment the reference count on the object
 -  * Returns:  Ref count
 -  */
 - 
 - HIDDEN ULONG STDMETHODCALLTYPE AddRef(LPWINEASIO iface)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl *)iface;
 -     ULONG           ref = InterlockedIncrement(&(This->ref));
 - 
 -     TRACE("iface: %p, ref count is %d\n", iface, ref);
 -     return ref;
 - }
 - 
 - /*
 -  * ULONG Release (LPWINEASIO iface);
 -  *  Function:   Destroy the interface
 -  *  Returns:    Ref count
 -  *  Implies:    ASIOStop() and ASIODisposeBuffers()
 -  */
 - 
 - HIDDEN ULONG STDMETHODCALLTYPE Release(LPWINEASIO iface)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl *)iface;
 -     ULONG            ref = InterlockedDecrement(&This->ref);
 -     int             i;
 - 
 -     TRACE("iface: %p, ref count is %d\n", iface, ref);
 - 
 -     if (This->asio_driver_state == Running)
 -         Stop(iface);
 -     if (This->asio_driver_state == Prepared)
 -         DisposeBuffers(iface);
 - 
 -     if (This->asio_driver_state == Initialized)
 -     {
 -         /* just for good measure we deinitialize IOChannel structures and unregister JACK ports */
 -         for (i = 0; i < This->wineasio_number_inputs; i++)
 -         {
 -             if(jack_port_unregister (This->jack_client, This->input_channel[i].port))
 -                 MESSAGE("Error trying to unregister port %s\n", This->input_channel[i].port_name);
 -             This->input_channel[i].active = ASIOFalse;
 -             This->input_channel[i].port = NULL;
 -         }
 -         for (i = 0; i < This->wineasio_number_outputs; i++)
 -         {
 -             if(jack_port_unregister (This->jack_client, This->output_channel[i].port))
 -                 MESSAGE("Error trying to unregister port %s\n", This->output_channel[i].port_name);
 -             This->output_channel[i].active = ASIOFalse;
 -             This->output_channel[i].port = NULL;
 -         }
 -         This->asio_active_inputs = This->asio_active_outputs = 0;
 -         TRACE("%i IOChannel structures released\n", This->wineasio_number_inputs + This->wineasio_number_outputs);
 - 
 -         if (This->jack_output_ports)
 -             jack_free (This->jack_output_ports);
 -         if (This->jack_input_ports)
 -             jack_free (This->jack_input_ports);
 - 
 -         if (This->jack_client)
 -             if (jack_client_close(This->jack_client))
 -                 MESSAGE("Error trying to close JACK client\n");
 - 
 -         if (This->input_channel)
 -             HeapFree(GetProcessHeap(), 0, This->input_channel);
 -     }
 -     TRACE("WineASIO terminated\n\n");
 -     if (ref == 0)
 -         HeapFree(GetProcessHeap(), 0, This);
 -     return ref;
 - }
 - 
 - /*
 -  * ASIOBool Init (void *sysRef);
 -  *  Function:   Initialize the driver
 -  *  Parameters: Pointer to "This"
 -  *              sysHanle is 0 on OS/X and on windows it contains the applications main window handle
 -  *  Returns:    ASIOFalse on error, and ASIOTrue on success
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(Init,8)
 - HIDDEN ASIOBool STDMETHODCALLTYPE Init(LPWINEASIO iface, void *sysRef)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl *)iface;
 -     jack_status_t   jack_status;
 -     jack_options_t  jack_options = JackNullOption;
 -     int             i;
 - 
 -     TRACE("iface: %p, sysRef: %p\n", iface, sysRef);
 - 
 -     This->sys_ref = sysRef;
 - 
 - #ifdef __WINESRC__
 -     mlockall(MCL_FUTURE);
 - #endif
 - 
 -     if (!configure_driver(This))
 -     {
 -         WARN("Unable to configure WineASIO\n");
 -         return ASIOFalse;
 -     }
 - 
 -     if (!This->wineasio_autostart_server)
 -         jack_options |= JackNoStartServer;
 -     This->jack_client = jack_client_open(This->jack_client_name, jack_options, &jack_status);
 - 
 -     if (This->jack_client == NULL)
 -     {
 -         WARN("Unable to open a JACK client as: %s\n", This->jack_client_name);
 -         return ASIOFalse;
 -     }
 -     TRACE("JACK client opened as: '%s'\n", jack_get_client_name(This->jack_client));
 - 
 -     if (!(This->asio_sample_rate = jack_get_sample_rate(This->jack_client)))
 -     {
 -         WARN("Unable to get samplerate from JACK\n");
 -         return ASIOFalse;
 -     }
 - 
 -     if (!(This->asio_current_buffersize = jack_get_buffer_size(This->jack_client)))
 -     {
 -         WARN("Unable to get buffer size from JACK\n");
 -         return ASIOFalse;
 -     }
 - 
 -     /* Allocate IOChannel structures */
 -     This->input_channel = HeapAlloc(GetProcessHeap(), 0, (This->wineasio_number_inputs + This->wineasio_number_outputs) * sizeof(IOChannel));
 -     if (!This->input_channel)
 -     {
 -         jack_client_close(This->jack_client);
 -         ERR("Unable to allocate IOChannel structures for %i channels\n", This->wineasio_number_inputs);
 -         return ASIOFalse;
 -     }
 -     This->output_channel = This->input_channel + This->wineasio_number_inputs;
 -     TRACE("%i IOChannel structures allocated\n", This->wineasio_number_inputs + This->wineasio_number_outputs);
 - 
 -     /* Get and count physical JACK ports */
 -     This->jack_input_ports = jack_get_ports(This->jack_client, NULL, NULL, JackPortIsPhysical | JackPortIsOutput);
 -     for (This->jack_num_input_ports = 0; This->jack_input_ports && This->jack_input_ports[This->jack_num_input_ports]; This->jack_num_input_ports++)
 -         ;
 -     This->jack_output_ports = jack_get_ports(This->jack_client, NULL, NULL, JackPortIsPhysical | JackPortIsInput);
 -     for (This->jack_num_output_ports = 0; This->jack_output_ports && This->jack_output_ports[This->jack_num_output_ports]; This->jack_num_output_ports++)
 -         ;
 - 
 -     /* Initialize IOChannel structures */
 -     for (i = 0; i < This->wineasio_number_inputs; i++)
 -     {
 -         This->input_channel[i].active = ASIOFalse;
 -         This->input_channel[i].port = NULL;
 -         snprintf(This->input_channel[i].port_name, ASIO_MAX_NAME_LENGTH, "in_%i", i + 1);
 -         This->input_channel[i].port = jack_port_register(This->jack_client,
 -             This->input_channel[i].port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, i);
 -         /* TRACE("IOChannel structure initialized for input %d: '%s'\n", i, This->input_channel[i].port_name); */
 -     }
 -     for (i = 0; i < This->wineasio_number_outputs; i++)
 -     {
 -         This->output_channel[i].active = ASIOFalse;
 -         This->output_channel[i].port = NULL;
 -         snprintf(This->output_channel[i].port_name, ASIO_MAX_NAME_LENGTH, "out_%i", i + 1);
 -         This->output_channel[i].port = jack_port_register(This->jack_client,
 -             This->output_channel[i].port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, i);
 -         /* TRACE("IOChannel structure initialized for output %d: '%s'\n", i, This->output_channel[i].port_name); */
 -     }
 -     TRACE("%i IOChannel structures initialized\n", This->wineasio_number_inputs + This->wineasio_number_outputs);
 - 
 - #ifdef __WINESRC__
 -     jack_set_thread_creator(jack_thread_creator);
 - #endif
 - 
 -     if (jack_set_process_callback(This->jack_client, process_callback, This))
 -     {
 -         jack_client_close(This->jack_client);
 -         HeapFree(GetProcessHeap(), 0, This->input_channel);
 -         ERR("Unable to register JACK process callback\n");
 -         return ASIOFalse;
 -     }
 - 
 -     if (jack_set_buffer_size_callback(This->jack_client, bufsize_callback, This))
 -     {
 -         jack_client_close(This->jack_client);
 -         HeapFree(GetProcessHeap(), 0, This->input_channel);
 -         ERR("Unable to register JACK buffersize change callback\n");
 -         return ASIOFalse;
 -     }
 - 
 -     if (jack_set_sample_rate_callback (This->jack_client, srate_callback, This))
 -     {
 -         jack_client_close(This->jack_client);
 -         HeapFree(GetProcessHeap(), 0, This->input_channel);
 -         ERR("Unable to register JACK samplerate change callback\n");
 -         return ASIOFalse;
 -     }
 - 
 -     This->asio_driver_state = Initialized;
 -     TRACE("WineASIO 0.%.1f initialized\n",(float) This->asio_version / 10);
 -     return ASIOTrue;
 - }
 - 
 - /*
 -  * void GetDriverName(char *name);
 -  *  Function:    Returns the driver name in name
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetDriverName,8)
 - HIDDEN void STDMETHODCALLTYPE GetDriverName(LPWINEASIO iface, char *name)
 - {
 -     TRACE("iface: %p, name: %p\n", iface, name);
 -     strcpy(name, "WineASIO");
 -     return;
 - }
 - 
 - /*
 -  * LONG GetDriverVersion (void);
 -  *  Function:    Returns the driver version number
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetDriverVersion,4)
 - HIDDEN LONG STDMETHODCALLTYPE GetDriverVersion(LPWINEASIO iface)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p\n", iface);
 -     return This->asio_version;
 - }
 - 
 - /*
 -  * void GetErrorMessage(char *string);
 -  *  Function:    Returns an error message for the last occured error in string
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetErrorMessage,8)
 - HIDDEN void STDMETHODCALLTYPE GetErrorMessage(LPWINEASIO iface, char *string)
 - {
 -     TRACE("iface: %p, string: %p)\n", iface, string);
 -     strcpy(string, "WineASIO does not return error messages\n");
 -     return;
 - }
 - 
 - /*
 -  * ASIOError Start(void);
 -  *  Function:    Start JACK IO processing and reset the sample counter to zero
 -  *  Returns:     ASE_NotPresent if IO is missing
 -  *               ASE_HWMalfunction if JACK fails to start
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(Start,4)
 - HIDDEN ASIOError STDMETHODCALLTYPE Start(LPWINEASIO iface)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 -     int             i;
 - 
 - #ifndef _WIN64
 -     DWORD           temp_time;
 - #endif
 - 
 -     TRACE("iface: %p\n", iface);
 - 
 -     if (This->asio_driver_state != Prepared)
 -     {
 -         ERR("Unable to start WineASIO\n");
 -         return ASE_NotPresent;
 -     }
 - 
 -     /* Zero the audio buffer */
 -     for (i = 0; i < (This->wineasio_number_inputs + This->wineasio_number_outputs) * 2 * This->asio_current_buffersize; i++)
 -         This->callback_audio_buffer[i] = 0;
 - 
 -     /* prime the callback */
 -     This->asio_buffer_index =  0;
 -     if (This->asio_callbacks)
 -     {
 - #ifdef _WIN64
 -         This->asio_sample_position = 0;
 -         This->asio_time_stamp = timeGetTime() * 1000000;
 - #else
 -         This->asio_sample_position.hi = This->asio_sample_position.lo = 0;
 -         temp_time = timeGetTime();
 -         This->asio_time_stamp.lo = temp_time * 1000000;
 -         This->asio_time_stamp.hi = ((unsigned long long) temp_time * 1000000) >> 32;
 - #endif
 -         This->asio_time_info_mode = FALSE;
 -         This->asio_can_time_code = FALSE;
 - 
 -         if (This->asio_callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0))
 -         {
 -             TRACE("TimeInfo mode enabled\n");
 -             This->asio_time_info_mode = TRUE;
 - #ifdef _WIN64
 -             This->asio_time.timeInfo.systemTime = This->asio_time_stamp;
 -             This->asio_time.timeInfo.samplePosition = 0;
 - #else
 -             This->asio_time.timeInfo.systemTime.hi = This->asio_time_stamp.hi;
 -             This->asio_time.timeInfo.systemTime.lo = This->asio_time_stamp.lo;
 -             This->asio_time.timeInfo.samplePosition.hi = This->asio_time.timeInfo.samplePosition.lo = 0;
 - #endif
 -             This->asio_time.timeCode.speed = 0;
 -             This->asio_time.timeInfo.sampleRate = This->asio_sample_rate;
 -             This->asio_time.timeInfo.flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid;
 -             if (This->asio_callbacks->asioMessage(kAsioSupportsTimeCode,  0, 0, 0))
 -             {
 -                 TRACE("TimeCode supported\n");
 -                 This->asio_can_time_code = TRUE;
 - #ifdef _WIN64
 -                 This->asio_time.timeCode.timeCodeSamples = This->asio_time_stamp;
 - #else
 -                 This->asio_time.timeCode.timeCodeSamples.hi = This->asio_time_stamp.hi;
 -                 This->asio_time.timeCode.timeCodeSamples.lo = This->asio_time_stamp.lo;
 - #endif
 -                 This->asio_time.timeCode.flags = ~(kTcValid | kTcRunning);
 -             }
 -             This->asio_callbacks->bufferSwitchTimeInfo(&This->asio_time, This->asio_buffer_index, ASIOTrue);
 -         }
 -         else
 -         {
 -             TRACE("Runnning simple BufferSwitch() callback\n");
 -             This->asio_callbacks->bufferSwitch(This->asio_buffer_index, ASIOTrue);
 -         }
 -         This->asio_buffer_index = This->asio_buffer_index ? 0 : 1;
 -     }
 -     else
 -     {
 -         WARN("The ASIO host supplied no callback structure\n");
 -         return ASE_NotPresent;
 -     }
 - 
 -     if (jack_activate(This->jack_client))
 -     {
 -         ERR("Unable to activate JACK client\n");
 -         return ASE_NotPresent;
 -     }
 - 
 -     /* connect to the hardware io */
 -     if (This->wineasio_connect_to_hardware)
 -     {
 -         for (i = 0; i < This->jack_num_input_ports && i < This->wineasio_number_inputs; i++)
 -         {
 -             /* TRACE("Connecting JACK port: %s to asio: %s\n", This->jack_input_ports[i], jack_port_name(This->input_channel[i].port)); */
 -             if (strstr(jack_port_type(jack_port_by_name(This->jack_client, This->jack_input_ports[i])), "audio"))
 -                 if (jack_connect(This->jack_client, This->jack_input_ports[i], jack_port_name(This->input_channel[i].port)))
 -                     WARN("Unable to connect %s to %s\n", This->jack_input_ports[i], jack_port_name(This->input_channel[i].port));
 -         }
 -         for (i = 0; i < This->jack_num_output_ports && i < This->wineasio_number_outputs; i++)
 -         {
 -             /* TRACE("Connecting asio: %s to jack port: %s\n", jack_port_name(This->output_channel[i].port), This->jack_output_ports[i]); */
 -             if (strstr(jack_port_type(jack_port_by_name(This->jack_client, This->jack_output_ports[i])), "audio"))
 -                 if (jack_connect(This->jack_client, jack_port_name(This->output_channel[i].port), This->jack_output_ports[i]))
 -                     WARN("Unable to connect to %s\n", jack_port_name(This->output_channel[i].port));
 -         }
 -     }
 - 
 -     This->asio_driver_state = Running;
 -     TRACE("WineASIO successfully loaded\n");
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError Stop(void);
 -  *  Function:   Stop JACK IO processing
 -  *  Returns:    ASE_NotPresent on missing IO
 -  *  Note:       BufferSwitch() must not called after returning
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(Stop,4)
 - HIDDEN ASIOError STDMETHODCALLTYPE Stop(LPWINEASIO iface)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p\n", iface);
 - 
 -     if (This->asio_driver_state != Running)
 -     {
 -         WARN("Unable to stop WineASIO, not running\n");
 -         return ASE_NotPresent;
 -     }
 - 
 -     This->asio_driver_state = Prepared;
 - 
 -     if (jack_deactivate(This->jack_client))
 -     {
 -         ERR("Unable to deactivate JACK client\n");
 -         return ASE_NotPresent;
 -     }
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetChannels(LONG *numInputChannels, LONG *numOutputChannels);
 -  *  Function:   Report number of IO channels
 -  *  Parameters: numInputChannels and numOutputChannels will hold number of channels on returning
 -  *  Returns:    ASE_NotPresent if no channels are available, otherwise AES_OK
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetChannels,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetChannels (LPWINEASIO iface, LONG *numInputChannels, LONG *numOutputChannels)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     if (!numInputChannels && !numOutputChannels)
 -     {
 -         WARN("Nullpointer argument\n");
 -         return ASE_InvalidParameter;
 -     }
 - 
 -     *numInputChannels = This->wineasio_number_inputs;
 -     *numOutputChannels = This->wineasio_number_outputs;
 -     TRACE("iface: %p, inputs: %i, outputs: %i\n", iface, This->wineasio_number_inputs, This->wineasio_number_outputs);
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetLatencies(LONG *inputLatency, LONG *outputLatency);
 -  *  Function:   Return latency in frames
 -  *  Returns:    ASE_NotPresent if no IO is available, otherwise AES_OK
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetLatencies,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetLatencies(LPWINEASIO iface, LONG *inputLatency, LONG *outputLatency)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     if (!inputLatency && !outputLatency)
 -     {
 -         WARN("Nullpointer argument\n");
 -         return ASE_InvalidParameter;
 -     }
 - 
 -     *inputLatency = *outputLatency = This->asio_current_buffersize;
 -     TRACE("iface: %p Latency = %i frames\n", iface, This->asio_current_buffersize);
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetBufferSize(LONG *minSize, LONG *maxSize, LONG *preferredSize, LONG *granularity);
 -  *  Function:    Return minimum, maximum, preferred buffer sizes, and granularity
 -  *               At the moment return all the same, and granularity 0
 -  *  Returns:    ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetBufferSize,20)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetBufferSize(LPWINEASIO iface, LONG *minSize, LONG *maxSize, LONG *preferredSize, LONG *granularity)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p, minSize: %p, maxSize: %p, preferredSize: %p, granularity: %p\n", iface, minSize, maxSize, preferredSize, granularity);
 - 
 -     if (!minSize && !maxSize && !preferredSize && !granularity)
 -     {
 -         WARN("Nullpointer argument\n");
 -         return ASE_InvalidParameter;
 -     }
 - 
 -     if (This->wineasio_fixed_buffersize)
 -     {
 -         *minSize = *maxSize = *preferredSize = This->asio_current_buffersize;
 -         *granularity = 0;
 -         TRACE("Buffersize fixed at %i\n", This->asio_current_buffersize);
 -         return ASE_OK;
 -     }
 - 
 -     *minSize = ASIO_MINIMUM_BUFFERSIZE;
 -     *maxSize = ASIO_MAXIMUM_BUFFERSIZE;
 -     *preferredSize = This->wineasio_preferred_buffersize;
 -     *granularity = -1;
 -     TRACE("The ASIO host can control buffersize\nMinimum: %i, maximum: %i, preferred: %i, granularity: %i, current: %i\n",
 -           *minSize, *maxSize, *preferredSize, *granularity, This->asio_current_buffersize);
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError CanSampleRate(ASIOSampleRate sampleRate);
 -  *  Function:   Ask if specific SR is available
 -  *  Returns:    ASE_NoClock if SR isn't available, ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(CanSampleRate,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE CanSampleRate(LPWINEASIO iface, ASIOSampleRate sampleRate)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p, Samplerate = %li, requested samplerate = %li\n", iface, (long) This->asio_sample_rate, (long) sampleRate);
 - 
 -     if (sampleRate != This->asio_sample_rate)
 -         return ASE_NoClock;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetSampleRate(ASIOSampleRate *currentRate);
 -  *  Function:   Return current SR
 -  *  Parameters: currentRate will hold SR on return, 0 if unknown
 -  *  Returns:    ASE_NoClock if SR is unknown, ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetSampleRate,8)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetSampleRate(LPWINEASIO iface, ASIOSampleRate *sampleRate)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p, Sample rate is %i\n", iface, (int) This->asio_sample_rate);
 - 
 -     if (!sampleRate)
 -     {
 -         WARN("Nullpointer argument\n");
 -         return ASE_InvalidParameter;
 -     }
 -     *sampleRate = This->asio_sample_rate;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError SetSampleRate(ASIOSampleRate sampleRate);
 -  *  Function:   Set requested SR, enable external sync if SR == 0
 -  *  Returns:    ASE_NoClock if unknown SR
 -  *              ASE_InvalidMode if current clock is external and SR != 0
 -  *              ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(SetSampleRate,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE SetSampleRate(LPWINEASIO iface, ASIOSampleRate sampleRate)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p, Sample rate %f requested\n", iface, sampleRate);
 - 
 -     if (sampleRate != This->asio_sample_rate)
 -         return ASE_NoClock;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetClockSources(ASIOClockSource *clocks, LONG *numSources);
 -  *  Function:   Return available clock sources
 -  *  Parameters: clocks - a pointer to an array of ASIOClockSource structures.
 -  *              numSources - when called: number of allocated members
 -  *                         - on return: number of clock sources, the minimum is 1 - the internal clock
 -  *  Returns:    ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetClockSources,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetClockSources(LPWINEASIO iface, ASIOClockSource *clocks, LONG *numSources)
 - {
 -     TRACE("iface: %p, clocks: %p, numSources: %p\n", iface, clocks, numSources);
 - 
 -     if (!clocks && !numSources)
 -     {
 -         WARN("Nullpointer argument\n");
 -         return ASE_InvalidParameter;
 -     }
 -     clocks->index = 0;
 -     clocks->associatedChannel = -1;
 -     clocks->associatedGroup = -1;
 -     clocks->isCurrentSource = ASIOTrue;
 -     strcpy(clocks->name, "Internal");
 -     *numSources = 1;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError SetClockSource(LONG index);
 -  *  Function:   Set clock source
 -  *  Parameters: index returned by ASIOGetClockSources() - See asio.h for more details
 -  *  Returns:    ASE_NotPresent on missing IO
 -  *              ASE_InvalidMode may be returned if a clock can't be selected
 -  *              ASE_NoClock should not be returned
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(SetClockSource,8)
 - HIDDEN ASIOError STDMETHODCALLTYPE SetClockSource(LPWINEASIO iface, LONG index)
 - {
 -     TRACE("iface: %p, index: %i\n", iface, index);
 - 
 -     if (index != 0)
 -         return ASE_NotPresent;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);
 -  *  Function:   Return sample position and timestamp
 -  *  Parameters: sPos holds the position on return, reset to 0 on ASIOStart()
 -  *              tStamp holds the system time of sPos
 -  *  Return:     ASE_NotPresent on missing IO
 -  *              ASE_SPNotAdvancing on missing clock
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetSamplePosition,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetSamplePosition(LPWINEASIO iface, ASIOSamples *sPos, ASIOTimeStamp *tStamp)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     TRACE("iface: %p, sPos: %p, tStamp: %p\n", iface, sPos, tStamp);
 - 
 -     if (!sPos && !tStamp)
 -     {
 -         WARN("Nullpointer argument\n");
 -         return ASE_InvalidParameter;
 -     }
 - #ifdef _WIN64
 -     *tStamp = This->asio_time_stamp;
 -     *sPos = This->asio_sample_position;
 - #else
 -     tStamp->lo = This->asio_time_stamp.lo;
 -     tStamp->hi = This->asio_time_stamp.hi;
 -     sPos->lo = This->asio_sample_position.lo;
 -     sPos->hi = 0;
 - #endif
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError GetChannelInfo (ASIOChannelInfo *info);
 -  *  Function:   Retrive channel info. - See asio.h for more detail
 -  *  Returns:    ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(GetChannelInfo,8)
 - HIDDEN ASIOError STDMETHODCALLTYPE GetChannelInfo(LPWINEASIO iface, ASIOChannelInfo *info)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 - 
 -     /* TRACE("(iface: %p, info: %p\n", iface, info); */
 - 
 -     if (info->channel < 0 || (info->isInput ? info->channel >= This->wineasio_number_inputs : info->channel >= This->wineasio_number_outputs))
 -     {
 -         TRACE("Invalid Parameter\n");
 -         return ASE_InvalidParameter;
 -     }
 - 
 -     info->channelGroup = 0;
 - 
 - #ifdef ASIOST32INT
 -     info->type = ASIOSTInt32LSB;
 - #else
 -     info->type = ASIOSTFloat32LSB;
 - #endif
 - 
 -     if (info->isInput)
 -     {
 -         info->isActive = This->input_channel[info->channel].active;
 -         memcpy(info->name, This->input_channel[info->channel].port_name, ASIO_MAX_NAME_LENGTH);
 -     }
 -     else
 -     {
 -         info->isActive = This->output_channel[info->channel].active;
 -         memcpy(info->name, This->output_channel[info->channel].port_name, ASIO_MAX_NAME_LENGTH);
 -     }
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError CreateBuffers(ASIOBufferInfo *bufferInfo, LONG numChannels, LONG bufferSize, ASIOCallbacks *asioCallbacks);
 -  *  Function:   Allocate buffers for IO channels
 -  *  Parameters: bufferInfo      - pointer to an array of ASIOBufferInfo structures
 -  *              numChannels     - the total number of IO channels to be allocated
 -  *              bufferSize      - one of the buffer sizes retrieved with ASIOGetBufferSize()
 -  *              asioCallbacks   - pointer to an ASIOCallbacks structure
 -  *              See asio.h for more detail
 -  *  Returns:    ASE_NoMemory if impossible to allocate enough memory
 -  *              ASE_InvalidMode on unsupported bufferSize or invalid bufferInfo data
 -  *              ASE_NotPresent on missing IO
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(CreateBuffers,20)
 - HIDDEN ASIOError STDMETHODCALLTYPE CreateBuffers(LPWINEASIO iface, ASIOBufferInfo *bufferInfo, LONG numChannels, LONG bufferSize, ASIOCallbacks *asioCallbacks)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 -     ASIOBufferInfo  *buffer_info = bufferInfo;
 -     int             i, j, k;
 - 
 -     TRACE("iface: %p, bufferInfo: %p, numChannels: %i, bufferSize: %i, asioCallbacks: %p\n", iface, bufferInfo, numChannels, bufferSize, asioCallbacks);
 - 
 -     if (This->asio_driver_state != Initialized)
 -     {
 -         WARN("Unable to create buffers, WineASIO is not in the initialized state\n");
 -         return ASE_NotPresent;
 -     }
 - 
 -     if (This->wineasio_fixed_buffersize)
 -     {
 -         if (This->asio_current_buffersize != bufferSize)
 -         {
 -             WARN("Invalid buffersize (%i) requested\n", bufferSize);
 -             return ASE_InvalidMode;
 -         }
 -         TRACE("Buffersize fixed at %i\n", This->asio_current_buffersize);
 -     }
 -     else
 -     { /* fail if not a power of two and if out of range */
 -         if (!(bufferSize > 0 && !(bufferSize&(bufferSize-1))
 -                 && bufferSize >= ASIO_MINIMUM_BUFFERSIZE
 -                 && bufferSize <= ASIO_MAXIMUM_BUFFERSIZE))
 -         {
 -             WARN("Invalid buffersize %i requested\n", bufferSize);
 -             return ASE_InvalidMode;
 -         }
 -         else
 -         {
 -             if (This->asio_current_buffersize == bufferSize)
 -                 TRACE("Buffer size already set to %i\n", This->asio_current_buffersize);
 -             else
 -             {
 -                 This->asio_current_buffersize = bufferSize;
 -                 if (jack_set_buffer_size(This->jack_client, This->asio_current_buffersize))
 -                 {
 -                     WARN("JACK is unable to set buffersize to %i\n", This->asio_current_buffersize);
 -                     return ASE_HWMalfunction;
 -                 }
 -                 TRACE("Buffer size changed to %i\n", This->asio_current_buffersize);
 -             }
 -         }
 -     }
 - 
 -     This->asio_callbacks = asioCallbacks;
 -     if (!This->asio_callbacks->asioMessage)
 -     {
 -         WARN("No asioMessage callback supplied\n");
 -         return ASE_InvalidMode;
 -     }
 - 
 -     TRACE("The ASIO host supports ASIO v%i\n", (int) This->asio_callbacks->asioMessage(kAsioEngineVersion,  0, 0, 0));
 - 
 -     if (This->asio_callbacks->asioMessage(kAsioSelectorSupported, kAsioResetRequest, 0 , 0))
 -         TRACE("The ASIO host supports kAsioResetRequest\n");
 - 
 -     if (This->asio_callbacks->asioMessage(kAsioSelectorSupported, kAsioResyncRequest, 0 , 0))
 -         TRACE("The ASIO host supports kAsioResyncRequest\n");
 - 
 -     if (This->asio_callbacks->asioMessage(kAsioSelectorSupported, kAsioBufferSizeChange, 0 , 0))
 -         TRACE("The ASIO host supports kAsioBufferSizeChange\n");
 - 
 -     /* Check for invalid channel numbers */
 -     for (i = j = k = 0; i < numChannels; i++, buffer_info++)
 -     {
 -         if (buffer_info->isInput)
 -         {
 -             if (j++ >= This->wineasio_number_inputs)
 -             {
 -                 WARN("Invalid input channel requested\n");
 -                 return ASE_InvalidMode;
 -             }
 -         }
 -         else
 -         {
 -             if (k++  >= This->wineasio_number_outputs)
 -             {
 -                 WARN("Invalid output channel requested\n");
 -                 return ASE_InvalidMode;
 -             }
 -         }
 -     }
 - 
 -     /* Allocate audio buffers */
 -     This->callback_audio_buffer = HeapAlloc(GetProcessHeap(), 0,
 -         (This->wineasio_number_inputs + This->wineasio_number_outputs) * 2 * This->asio_current_buffersize * sizeof(jack_default_audio_sample_t));
 -     if (!This->callback_audio_buffer)
 -     {
 -         ERR("Unable to allocate %i ASIO audio buffers\n", This->wineasio_number_inputs + This->wineasio_number_outputs);
 -         return ASE_NoMemory;
 -     }
 -     TRACE("%i ASIO audio buffers allocated (%i kB)\n", This->wineasio_number_inputs + This->wineasio_number_outputs,
 -           (int) ((This->wineasio_number_inputs + This->wineasio_number_outputs) * 2 * This->asio_current_buffersize * sizeof(jack_default_audio_sample_t) / 1024));
 - 
 -     for (i = 0; i < This->wineasio_number_inputs; i++)
 -         This->input_channel[i].audio_buffer = This->callback_audio_buffer + (i * 2 * This->asio_current_buffersize);
 -     for (i = 0; i < This->wineasio_number_outputs; i++)
 -         This->output_channel[i].audio_buffer = This->callback_audio_buffer + ((This->wineasio_number_inputs + i) * 2 * This->asio_current_buffersize);
 - 
 -      /* initialize ASIOBufferInfo structures */
 -     buffer_info = bufferInfo;
 -     This->asio_active_inputs = This->asio_active_outputs = 0;
 -     for (i = 0; i < numChannels; i++, buffer_info++)
 -     {
 -         if (buffer_info->isInput)
 -         {
 -             buffer_info->buffers[0] = &This->input_channel[This->asio_active_inputs].audio_buffer[0];
 -             buffer_info->buffers[1] = &This->input_channel[This->asio_active_inputs].audio_buffer[This->asio_current_buffersize];
 -             This->input_channel[This->asio_active_inputs].active = ASIOTrue;
 -             This->asio_active_inputs++;
 -             /* TRACE("ASIO audio buffer for channel %i as input %li created\n", i, This->asio_active_inputs); */
 -         }
 -         else
 -         {
 -             buffer_info->buffers[0] = &This->output_channel[This->asio_active_outputs].audio_buffer[0];
 -             buffer_info->buffers[1] = &This->output_channel[This->asio_active_outputs].audio_buffer[This->asio_current_buffersize];
 -             This->output_channel[This->asio_active_outputs].active = ASIOTrue;
 -             This->asio_active_outputs++;
 -             /* TRACE("ASIO audio buffer for channel %i as output %li created\n", i, This->asio_active_outputs); */
 -         }
 -     }
 -     TRACE("%i audio channels initialized\n", This->asio_active_inputs + This->asio_active_outputs);
 - 
 -     /* check for TimeInfo or TimeCode mode */
 -     if (This->asio_callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0))
 -     {
 -         This->asio_time_info_mode = TRUE;
 -         if (This->asio_callbacks->asioMessage(kAsioSupportsTimeCode,  0, 0, 0))
 -             This->asio_can_time_code = TRUE;
 -     }
 -     else
 -         This->asio_time_info_mode = FALSE;
 - 
 -     This->asio_driver_state = Prepared;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError DisposeBuffers(void);
 -  *  Function:   Release allocated buffers
 -  *  Returns:    ASE_InvalidMode if no buffers were previously allocated
 -  *              ASE_NotPresent on missing IO
 -  *  Implies:    ASIOStop()
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(DisposeBuffers,4)
 - HIDDEN ASIOError STDMETHODCALLTYPE DisposeBuffers(LPWINEASIO iface)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)iface;
 -     int             i;
 - 
 -     TRACE("iface: %p\n", iface);
 - 
 -     if (This->asio_driver_state == Running)
 -         Stop (iface);
 -     if (This->asio_driver_state != Prepared)
 -     {
 -         WARN("Unable to dispose buffers, wrong driver state\n");
 -         return ASE_NotPresent;
 -     }
 - 
 -     This->asio_callbacks = NULL;
 - 
 -     for (i = 0; i < This->wineasio_number_inputs; i++)
 -     {
 -         This->input_channel[i].audio_buffer = NULL;
 -         This->input_channel[i].active = ASIOFalse;
 -     }
 -     for (i = 0; i < This->wineasio_number_outputs; i++)
 -     {
 -         This->output_channel[i].audio_buffer = NULL;
 -         This->output_channel[i].active = ASIOFalse;
 -     }
 -     This->asio_active_inputs = This->asio_active_outputs = 0;
 - 
 -     if (This->callback_audio_buffer)
 -         HeapFree(GetProcessHeap(), 0, This->callback_audio_buffer);
 - 
 -     This->asio_driver_state = Initialized;
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError ControlPanel(void);
 -  *  Function:   Open a control panel for driver settings
 -  *  Returns:    ASE_NotPresent if no control panel exists.  Actually return code should be ignored
 -  *  Note:       Call the asioMessage callback if something has changed
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(ControlPanel,4)
 - HIDDEN ASIOError STDMETHODCALLTYPE ControlPanel(LPWINEASIO iface)
 - {
 -     char    *arg_list[] = { strdup ("qjackctl"), NULL };
 - 
 -     TRACE("iface: %p\n", iface);
 - 
 -     if (!fork())
 -         execvp (arg_list[0], arg_list);
 -     return ASE_OK;
 - }
 - 
 - /*
 -  * ASIOError Future(LONG selector, void *opt);
 -  *  Function:   Various, See asio.h for more detail
 -  *  Returns:    Depends on the selector but in general ASE_InvalidParameter on invalid selector
 -  *              ASE_InvalidParameter if function is unsupported to disable further calls
 -  *              ASE_SUCCESS on success, do not use AES_OK
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(Future,12)
 - HIDDEN ASIOError STDMETHODCALLTYPE Future(LPWINEASIO iface, LONG selector, void *opt)
 - {
 -     IWineASIOImpl           *This = (IWineASIOImpl *) iface;
 - 
 -     TRACE("iface: %p, selector: %i, opt: %p\n", iface, selector, opt);
 - 
 -     switch (selector)
 -     {
 -         case kAsioEnableTimeCodeRead:
 -             This->asio_can_time_code = TRUE;
 -             TRACE("The ASIO host enabled TimeCode\n");
 -             return ASE_SUCCESS;
 -         case kAsioDisableTimeCodeRead:
 -             This->asio_can_time_code = FALSE;
 -             TRACE("The ASIO host disabled TimeCode\n");
 -             return ASE_SUCCESS;
 -         case kAsioSetInputMonitor:
 -             TRACE("The driver denied request to set input monitor\n");
 -             return ASE_NotPresent;
 -         case kAsioTransport:
 -             TRACE("The driver denied request for ASIO Transport control\n");
 -             return ASE_InvalidParameter;
 -         case kAsioSetInputGain:
 -             TRACE("The driver denied request to set input gain\n");
 -             return ASE_InvalidParameter;
 -         case kAsioGetInputMeter:
 -             TRACE("The driver denied request to get input meter \n");
 -             return ASE_InvalidParameter;
 -         case kAsioSetOutputGain:
 -             TRACE("The driver denied request to set output gain\n");
 -             return ASE_InvalidParameter;
 -         case kAsioGetOutputMeter:
 -             TRACE("The driver denied request to get output meter\n");
 -             return ASE_InvalidParameter;
 -         case kAsioCanInputMonitor:
 -             TRACE("The driver does not support input monitor\n");
 -             return ASE_InvalidParameter;
 -         case kAsioCanTimeInfo:
 -             TRACE("The driver supports TimeInfo\n");
 -             return ASE_SUCCESS;
 -         case kAsioCanTimeCode:
 -             TRACE("The driver supports TimeCode\n");
 -             return ASE_SUCCESS;
 -         case kAsioCanTransport:
 -             TRACE("The driver denied request for ASIO Transport\n");
 -             return ASE_InvalidParameter;
 -         case kAsioCanInputGain:
 -             TRACE("The driver does not support input gain\n");
 -             return ASE_InvalidParameter;
 -         case kAsioCanInputMeter:
 -             TRACE("The driver does not support input meter\n");
 -             return ASE_InvalidParameter;
 -         case kAsioCanOutputGain:
 -             TRACE("The driver does not support output gain\n");
 -             return ASE_InvalidParameter;
 -         case kAsioCanOutputMeter:
 -             TRACE("The driver does not support output meter\n");
 -             return ASE_InvalidParameter;
 -         case kAsioSetIoFormat:
 -             TRACE("The driver denied request to set DSD IO format\n");
 -             return ASE_NotPresent;
 -         case kAsioGetIoFormat:
 -             TRACE("The driver denied request to get DSD IO format\n");
 -             return ASE_NotPresent;
 -         case kAsioCanDoIoFormat:
 -             TRACE("The driver does not support DSD IO format\n");
 -             return ASE_NotPresent;
 -         default:
 -             TRACE("ASIOFuture() called with undocumented selector\n");
 -             return ASE_InvalidParameter;
 -     }
 - }
 - 
 - /*
 -  * ASIOError OutputReady(void);
 -  *  Function:   Tells the driver that output bufffers are ready
 -  *  Returns:    ASE_OK if supported
 -  *              ASE_NotPresent to disable
 -  */
 - 
 - DEFINE_THISCALL_WRAPPER(OutputReady,4)
 - HIDDEN ASIOError STDMETHODCALLTYPE OutputReady(LPWINEASIO iface)
 - {
 -     /* disabled to stop stand alone NI programs from spamming the console
 -     TRACE("iface: %p\n", iface); */
 -     return ASE_NotPresent;
 - }
 - 
 - /****************************************************************************
 -  *  JACK callbacks
 -  */
 - 
 - static int bufsize_callback(jack_nframes_t nframes, void *arg)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)arg;
 - 
 -     if(This->asio_driver_state != Running)
 -         return 0;
 - 
 -     if (This->asio_callbacks->asioMessage(kAsioSelectorSupported, kAsioResetRequest, 0 , 0))
 -         This->asio_callbacks->asioMessage(kAsioResetRequest, 0, 0, 0);
 -     return 0;
 - }
 - 
 - static int process_callback(jack_nframes_t nframes, void *arg)
 - {
 -     IWineASIOImpl               *This = (IWineASIOImpl*)arg;
 -     int                         i;
 -     jack_transport_state_t      jack_transport_state;
 -     jack_position_t             jack_position;
 - 
 - #ifdef ASIOST32INT
 -     jack_default_audio_sample_t *in, *out;
 -     jack_nframes_t              j;
 - #endif
 - 
 - #ifndef _WIN64
 -     DWORD                       temp_time;
 - #endif
 -     // Output silence if the ASIO callback isn't running yet
 -     if (This->asio_driver_state != Running)
 -     {
 -         for (i = 0; i < This->asio_active_outputs; i++)
 -             memset(jack_port_get_buffer(This->output_channel[i].port, nframes), 0, sizeof (jack_default_audio_sample_t) * nframes);
 -         return 0;
 -     }
 -     /* get the input data from JACK and copy it to the ASIO buffers */
 - #ifdef ASIOST32INT
 -     for (i = 0; i < This->asio_active_inputs; i++)
 -         if (This->input_channel[i].active == ASIOTrue)
 -         {
 -             in = jack_port_get_buffer(This->input_channel[i].port, nframes);
 -             for (j = 0; j < nframes; j++)
 -                 ((int *)This->input_channel[i].audio_buffer)[nframes * This->asio_buffer_index + j] = in[j] * 0x7fffffff;
 -         }
 - #else
 -     for (i = 0; i < This->asio_active_inputs; i++)
 -         if (This->input_channel[i].active == ASIOTrue)
 -             memcpy (&This->input_channel[i].audio_buffer[nframes * This->asio_buffer_index],
 -                     jack_port_get_buffer(This->input_channel[i].port, nframes),
 -                     sizeof (jack_default_audio_sample_t) * nframes);
 - #endif
 - 
 - #ifdef _WIN64
 -     This->asio_sample_position += nframes;
 -     This->asio_sample_position & 0xffffffff;    /* make 32bit since JACK's position is 32bit anyways */
 -     This->asio_time_stamp = timeGetTime() * 1000000;
 - #else
 -     This->asio_sample_position.lo += nframes;
 -     temp_time = timeGetTime();
 -     This->asio_time_stamp.lo = temp_time * 1000000;
 -     This->asio_time_stamp.hi = ((unsigned long long) temp_time * 1000000) >> 32;
 - #endif
 - 
 -     /* time info & time code */
 -     if (This->asio_time_info_mode)
 -     {
 - #ifdef _WIN64
 -         This->asio_time.timeInfo.samplePosition = This->asio_sample_position;
 -         This->asio_time.timeInfo.systemTime = This->asio_time_stamp;
 - #else
 -         This->asio_time.timeInfo.samplePosition.lo = This->asio_sample_position.lo;
 -         This->asio_time.timeInfo.samplePosition.hi = 0;
 -         This->asio_time.timeInfo.systemTime.lo = This->asio_time_stamp.lo;
 -         This->asio_time.timeInfo.systemTime.hi = This->asio_time_stamp.hi;
 - #endif
 -         This->asio_time.timeInfo.sampleRate = This->asio_sample_rate;
 -         This->asio_time.timeInfo.flags  = kSystemTimeValid | kSamplePositionValid | kSampleRateValid;
 - 
 -         if (This->asio_can_time_code)
 -         {
 -             jack_transport_state = jack_transport_query(This->jack_client, &jack_position);
 - #ifdef _WIN64
 -             This->asio_time.timeCode.timeCodeSamples = jack_position.frame;
 - #else
 -             This->asio_time.timeCode.timeCodeSamples.lo = jack_position.frame;
 -             This->asio_time.timeCode.timeCodeSamples.hi = 0;
 - #endif
 -             This->asio_time.timeCode.flags = kTcValid;
 -             if (jack_transport_state == JackTransportRolling)
 -                 This->asio_time.timeCode.flags |= kTcRunning;
 -         }
 -         This->asio_callbacks->bufferSwitchTimeInfo(&This->asio_time, This->asio_buffer_index, ASIOTrue);
 -     }
 -     else
 -         This->asio_callbacks->bufferSwitch(This->asio_buffer_index, ASIOTrue);
 - 
 -     /* copy the ASIO data to JACK */
 - #ifdef ASIOST32INT
 -     for (i = 0; i < This->asio_active_outputs; i++)
 -         if (This->output_channel[i].active == ASIOTrue)
 -         {
 -             out = jack_port_get_buffer(This->output_channel[i].port, nframes);
 -             for (j = 0; j < nframes; j++)
 -                 out[j] = ((int *) This->output_channel[i].audio_buffer)[nframes * This->asio_buffer_index + j] / (float) 0x7fffffff;
 -         }
 - #else
 -     for (i = 0; i < This->asio_active_outputs; i++)
 -         if (This->output_channel[i].active == ASIOTrue)
 -             memcpy(jack_port_get_buffer(This->output_channel[i].port, nframes),
 -                     &This->output_channel[i].audio_buffer[nframes * This->asio_buffer_index],
 -                     sizeof (jack_default_audio_sample_t) * nframes);
 - #endif
 -     This->asio_buffer_index = This->asio_buffer_index ? 0 : 1;
 -     return 0;
 - }
 - 
 - static int srate_callback(jack_nframes_t nframes, void *arg)
 - {
 -     IWineASIOImpl   *This = (IWineASIOImpl*)arg;
 - 
 -     if(This->asio_driver_state != Running)
 -         return 0;
 - 
 -     This->asio_sample_rate = nframes;
 -     This->asio_callbacks->sampleRateDidChange(nframes);
 -     return 0;
 - }
 - 
 - /*****************************************************************************
 -  *  Support functions
 -  */
 - 
 - #ifdef __WINESRC__
 - /* Function called by JACK to create a thread in the wine process context,
 -  *  uses the global structure jack_thread_creator_privates to communicate with jack_thread_creator_helper() */
 - static int jack_thread_creator(pthread_t* thread_id, const pthread_attr_t* attr, void *(*function)(void*), void* arg)
 - {
 -     TRACE("arg: %p, thread_id: %p, attr: %p, function: %p\n", arg, thread_id, attr, function);
 - 
 -     jack_thread_creator_privates.jack_callback_thread = function;
 -     jack_thread_creator_privates.arg = arg;
 -     jack_thread_creator_privates.jack_callback_thread_created = CreateEventW(NULL, FALSE, FALSE, NULL);
 -     CreateThread( NULL, 0, jack_thread_creator_helper, arg, 0,0 );
 -     WaitForSingleObject(jack_thread_creator_privates.jack_callback_thread_created, INFINITE);
 -     *thread_id = jack_thread_creator_privates.jack_callback_pthread_id;
 -     return 0;
 - }
 - 
 - /* internal helper function for returning the posix thread_id of the newly created callback thread */
 - static DWORD WINAPI jack_thread_creator_helper(LPVOID arg)
 - {
 -     TRACE("arg: %p\n", arg);
 - 
 -     jack_thread_creator_privates.jack_callback_pthread_id = pthread_self();
 -     SetEvent(jack_thread_creator_privates.jack_callback_thread_created);
 -     jack_thread_creator_privates.jack_callback_thread(jack_thread_creator_privates.arg);
 -     return 0;
 - }
 - #endif
 - 
 - static BOOL configure_driver(IWineASIOImpl *This)
 - {
 -     HKEY    hkey;
 -     LONG    result, value;
 -     DWORD   type, size;
 -     WCHAR   application_path [MAX_PATH];
 -     WCHAR   *application_name;
 -     char    environment_variable[MAX_ENVIRONMENT_SIZE];
 - 
 -     /* Unicode strings used for the registry */
 -     static const WCHAR key_software_wine_wineasio[] =
 -         { 'S','o','f','t','w','a','r','e','\\',
 -           'W','i','n','e','\\',
 -           'W','i','n','e','A','S','I','O',0 };
 -     static const WCHAR value_wineasio_number_inputs[] =
 -         { 'N','u','m','b','e','r',' ','o','f',' ','i','n','p','u','t','s',0 };
 -     static const WCHAR value_wineasio_number_outputs[] =
 -         { 'N','u','m','b','e','r',' ','o','f',' ','o','u','t','p','u','t','s',0 };
 -     static const WCHAR value_wineasio_fixed_buffersize[] =
 -         { 'F','i','x','e','d',' ','b','u','f','f','e','r','s','i','z','e',0 };
 -     static const WCHAR value_wineasio_preferred_buffersize[] =
 -         { 'P','r','e','f','e','r','r','e','d',' ','b','u','f','f','e','r','s','i','z','e',0 };
 -     static const WCHAR wineasio_autostart_server[] =
 -         { 'A','u','t','o','s','t','a','r','t',' ','s','e','r','v','e','r',0 };
 -     static const WCHAR value_wineasio_connect_to_hardware[] =
 -         { 'C','o','n','n','e','c','t',' ','t','o',' ','h','a','r','d','w','a','r','e',0 };
 - 
 -     /* Initialise most member variables,
 -      * asio_sample_position, asio_time, & asio_time_stamp are initialized in Start()
 -      * jack_num_input_ports & jack_num_output_ports are initialized in Init() */
 -     This->asio_active_inputs = 0;
 -     This->asio_active_outputs = 0;
 -     This->asio_buffer_index = 0;
 -     This->asio_callbacks = NULL;
 -     This->asio_can_time_code = FALSE;
 -     This->asio_current_buffersize = 0;
 -     This->asio_driver_state = Loaded;
 -     This->asio_sample_rate = 0;
 -     This->asio_time_info_mode = FALSE;
 -     This->asio_version = 90;
 - 
 -     This->wineasio_number_inputs = 16;
 -     This->wineasio_number_outputs = 16;
 -     This->wineasio_autostart_server = FALSE;
 -     This->wineasio_connect_to_hardware = TRUE;
 -     This->wineasio_fixed_buffersize = TRUE;
 -     This->wineasio_preferred_buffersize = ASIO_PREFERRED_BUFFERSIZE;
 - 
 -     This->jack_client = NULL;
 -     This->jack_client_name[0] = 0;
 -     This->jack_input_ports = NULL;
 -     This->jack_output_ports = NULL;
 -     This->callback_audio_buffer = NULL;
 -     This->input_channel = NULL;
 -     This->output_channel = NULL;
 - 
 -     /* create registry entries with defaults if not present */
 -     result = RegCreateKeyExW(HKEY_CURRENT_USER, key_software_wine_wineasio, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
 -     if (result != ERROR_SUCCESS)
 -     {
 -         ERR("Unable to open registry\n");
 -         return FALSE;
 -     }
 - 
 -     /* get/set number of asio inputs */
 -     size = sizeof(DWORD);
 -     if (RegQueryValueExW(hkey, value_wineasio_number_inputs, NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
 -     {
 -         if (type == REG_DWORD)
 -             This->wineasio_number_inputs = value;
 -     }
 -     else
 -     {
 -         type = REG_DWORD;
 -         size = sizeof(DWORD);
 -         value = This->wineasio_number_inputs;
 -         result = RegSetValueExW(hkey, value_wineasio_number_inputs, 0, REG_DWORD, (LPBYTE) &value, size);
 -     }
 - 
 -     /* get/set number of asio outputs */
 -     size = sizeof(DWORD);
 -     if (RegQueryValueExW(hkey, value_wineasio_number_outputs, NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
 -     {
 -         if (type == REG_DWORD)
 -             This->wineasio_number_outputs = value;
 -     }
 -     else
 -     {
 -         type = REG_DWORD;
 -         size = sizeof(DWORD);
 -         value = This->wineasio_number_outputs;
 -         result = RegSetValueExW(hkey, value_wineasio_number_outputs, 0, REG_DWORD, (LPBYTE) &value, size);
 -     }
 - 
 -     /* allow changing of asio buffer sizes */
 -     size = sizeof(DWORD);
 -     if (RegQueryValueExW(hkey, value_wineasio_fixed_buffersize, NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
 -     {
 -         if (type == REG_DWORD)
 -             This->wineasio_fixed_buffersize = value;
 -     }
 -     else
 -     {
 -         type = REG_DWORD;
 -         size = sizeof(DWORD);
 -         value = This->wineasio_fixed_buffersize;
 -         result = RegSetValueExW(hkey, value_wineasio_fixed_buffersize, 0, REG_DWORD, (LPBYTE) &value, size);
 -     }
 - 
 -     /* preferred buffer size (if changing buffersize is allowed) */
 -     size = sizeof(DWORD);
 -     if (RegQueryValueExW(hkey, value_wineasio_preferred_buffersize, NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
 -     {
 -         if (type == REG_DWORD)
 -             This->wineasio_preferred_buffersize = value;
 -     }
 -     else
 -     {
 -         type = REG_DWORD;
 -         size = sizeof(DWORD);
 -         value = This->wineasio_preferred_buffersize;
 -         result = RegSetValueExW(hkey, value_wineasio_preferred_buffersize, 0, REG_DWORD, (LPBYTE) &value, size);
 -     }
 - 
 -     /* get/set JACK autostart */
 -     size = sizeof(DWORD);
 -     if (RegQueryValueExW(hkey, wineasio_autostart_server, NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
 -     {
 -         if (type == REG_DWORD)
 -             This->wineasio_autostart_server = value;
 -     }
 -     else
 -     {
 -         type = REG_DWORD;
 -         size = sizeof(DWORD);
 -         value = This->wineasio_autostart_server;
 -         result = RegSetValueExW(hkey, wineasio_autostart_server, 0, REG_DWORD, (LPBYTE) &value, size);
 -     }
 - 
 -     /* get/set JACK connect to physical io */
 -     size = sizeof(DWORD);
 -     if (RegQueryValueExW(hkey, value_wineasio_connect_to_hardware, NULL, &type, (LPBYTE) &value, &size) == ERROR_SUCCESS)
 -     {
 -         if (type == REG_DWORD)
 -             This->wineasio_connect_to_hardware = value;
 -     }
 -     else
 -     {
 -         type = REG_DWORD;
 -         size = sizeof(DWORD);
 -         value = This->wineasio_connect_to_hardware;
 -         result = RegSetValueExW(hkey, value_wineasio_connect_to_hardware, 0, REG_DWORD, (LPBYTE) &value, size);
 -     }
 - 
 -     /* get client name by stripping path and extension */
 -     GetModuleFileNameW(0, application_path, MAX_PATH);
 -     application_name = strrchrW(application_path, L'.');
 -     *application_name = 0;
 -     application_name = strrchrW(application_path, L'\\');
 -     application_name++;
 -     WideCharToMultiByte(CP_ACP, WC_SEPCHARS, application_name, -1, This->jack_client_name, ASIO_MAX_NAME_LENGTH, NULL, NULL);
 - 
 -     RegCloseKey(hkey);
 - 
 -     /* Look for environment variables to override registry config values */
 - 
 -     if (GetEnvironmentVariableA("WINEASIO_NUMBER_INPUTS", environment_variable, MAX_ENVIRONMENT_SIZE))
 -     {
 -         errno = 0;
 -         result = strtol(environment_variable, 0, 10);
 -         if (errno != ERANGE)
 -             This->wineasio_number_inputs = result;
 -     }
 - 
 -     if (GetEnvironmentVariableA("WINEASIO_NUMBER_OUTPUTS", environment_variable, MAX_ENVIRONMENT_SIZE))
 -     {
 -         errno = 0;
 -         result = strtol(environment_variable, 0, 10);
 -         if (errno != ERANGE)
 -             This->wineasio_number_outputs = result;
 -     }
 - 
 -     if (GetEnvironmentVariableA("WINEASIO_AUTOSTART_SERVER", environment_variable, MAX_ENVIRONMENT_SIZE))
 -     {
 -         if (!strcasecmp(environment_variable, "on"))
 -             This->wineasio_autostart_server = TRUE;
 -         else if (!strcasecmp(environment_variable, "off"))
 -             This->wineasio_autostart_server = FALSE;
 -     }
 - 
 -     if (GetEnvironmentVariableA("WINEASIO_CONNECT_TO_HARDWARE", environment_variable, MAX_ENVIRONMENT_SIZE))
 -     {
 -         if (!strcasecmp(environment_variable, "on"))
 -             This->wineasio_connect_to_hardware = TRUE;
 -         else if (!strcasecmp(environment_variable, "off"))
 -             This->wineasio_connect_to_hardware = FALSE;
 -     }
 - 
 -     if (GetEnvironmentVariableA("WINEASIO_FIXED_BUFFERSIZE", environment_variable, MAX_ENVIRONMENT_SIZE))
 -     {
 -         if (!strcasecmp(environment_variable, "on"))
 -             This->wineasio_fixed_buffersize = TRUE;
 -         else if (!strcasecmp(environment_variable, "off"))
 -             This->wineasio_fixed_buffersize = FALSE;
 -     }
 - 
 -     if (GetEnvironmentVariableA("WINEASIO_PREFERRED_BUFFERSIZE", environment_variable, MAX_ENVIRONMENT_SIZE))
 -     {
 -         errno = 0;
 -         result = strtol(environment_variable, 0, 10);
 -         if (errno != ERANGE)
 -             This->wineasio_preferred_buffersize = result;
 -     }
 - 
 -     /* over ride the JACK client name gotten from the application name */
 -     size = GetEnvironmentVariableA("WINEASIO_CLIENT_NAME", environment_variable, ASIO_MAX_NAME_LENGTH);
 -     if (size > 0 && size < ASIO_MAX_NAME_LENGTH)
 -         strcpy(This->jack_client_name, environment_variable);
 - 
 -     /* if wineasio_preferred_buffersize is not a power of two or if out of range, then set to ASIO_PREFERRED_BUFFERSIZE */
 -     if (!(This->wineasio_preferred_buffersize > 0 && !(This->wineasio_preferred_buffersize&(This->wineasio_preferred_buffersize-1))
 -             && This->wineasio_preferred_buffersize >= ASIO_MINIMUM_BUFFERSIZE
 -             && This->wineasio_preferred_buffersize <= ASIO_MAXIMUM_BUFFERSIZE))
 -         This->wineasio_preferred_buffersize = ASIO_PREFERRED_BUFFERSIZE;
 - 
 -     return TRUE;
 - }
 - 
 - /* Allocate the interface pointer and associate it with the vtbl/WineASIO object */
 - HRESULT WINAPI WineASIOCreateInstance(REFIID riid, LPVOID *ppobj)
 - {
 -     IWineASIOImpl   *pobj;
 - 
 -     TRACE("riid: %s, ppobj: %p\n", debugstr_guid(riid), ppobj);
 - 
 -     pobj = HeapAlloc(GetProcessHeap(), 0, sizeof(*pobj));
 -     if (pobj == NULL)
 -     {
 -         WARN("out of memory\n");
 -         return E_OUTOFMEMORY;
 -     }
 - 
 -     pobj->lpVtbl = &WineASIO_Vtbl;
 -     pobj->ref = 1;
 -     TRACE("pobj = %p\n", pobj);
 -     *ppobj = pobj;
 -     TRACE("return %p\n", *ppobj);
 -     return S_OK;
 - }
 
 
  |