[PATCH v2 1/5] winealsa: Move midi_init to unixlib.
Andrew Eikum
aeikum at codeweavers.com
Wed Mar 16 09:02:05 CDT 2022
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Tue, Mar 15, 2022 at 04:18:59PM +0000, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
> dlls/winealsa.drv/alsa.c | 1 +
> dlls/winealsa.drv/alsamidi.c | 265 +++++++++++++++++++++++++++++++++++
> dlls/winealsa.drv/midi.c | 250 ++-------------------------------
> dlls/winealsa.drv/unixlib.h | 34 +++++
> 4 files changed, 314 insertions(+), 236 deletions(-)
>
> diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c
> index cdc3d81d8cc..76e4b98caaf 100644
> --- a/dlls/winealsa.drv/alsa.c
> +++ b/dlls/winealsa.drv/alsa.c
> @@ -2444,6 +2444,7 @@ unixlib_entry_t __wine_unix_call_funcs[] =
> set_event_handle,
> is_started,
> get_prop_value,
> + midi_init,
>
> midi_seq_lock, /* temporary */
> };
> diff --git a/dlls/winealsa.drv/alsamidi.c b/dlls/winealsa.drv/alsamidi.c
> index ab4de4f7f9e..86e092bd977 100644
> --- a/dlls/winealsa.drv/alsamidi.c
> +++ b/dlls/winealsa.drv/alsamidi.c
> @@ -31,6 +31,7 @@
> #include <stdarg.h>
> #include <stdio.h>
> #include <pthread.h>
> +#include <alsa/asoundlib.h>
>
> #include "ntstatus.h"
> #define WIN32_NO_STATUS
> @@ -38,13 +39,23 @@
> #include "winbase.h"
> #include "winternl.h"
> #include "mmdeviceapi.h"
> +#include "mmddk.h"
>
> +#include "wine/debug.h"
> #include "wine/unixlib.h"
>
> #include "unixlib.h"
>
> +WINE_DEFAULT_DEBUG_CHANNEL(midi);
> +
> static pthread_mutex_t seq_mutex = PTHREAD_MUTEX_INITIALIZER;
>
> +static unsigned int num_dests, num_srcs;
> +static struct midi_dest dests[MAX_MIDIOUTDRV];
> +static struct midi_src srcs[MAX_MIDIINDRV];
> +static snd_seq_t *midi_seq;
> +static unsigned int seq_refs;
> +
> static void seq_lock(void)
> {
> pthread_mutex_lock(&seq_mutex);
> @@ -62,3 +73,257 @@ NTSTATUS midi_seq_lock(void *args)
>
> return STATUS_SUCCESS;
> }
> +
> +static int seq_open(void)
> +{
> + static int midi_warn;
> +
> + seq_lock();
> + if (seq_refs == 0)
> + {
> + if (snd_seq_open(&midi_seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0)
> + {
> + if (!midi_warn)
> + WARN("Error opening ALSA sequencer.\n");
> + midi_warn = 1;
> + seq_unlock();
> + return -1;
> + }
> + }
> + seq_refs++;
> + seq_unlock();
> + return 0;
> +}
> +
> +static void seq_close(void)
> +{
> + seq_lock();
> + if (--seq_refs == 0)
> + {
> + snd_seq_close(midi_seq);
> + midi_seq = NULL;
> + }
> + seq_unlock();
> +}
> +
> +static int alsa_to_win_device_type(unsigned int type)
> +{
> + /* MOD_MIDIPORT output port
> + * MOD_SYNTH generic internal synth
> + * MOD_SQSYNTH square wave internal synth
> + * MOD_FMSYNTH FM internal synth
> + * MOD_MAPPER MIDI mapper
> + * MOD_WAVETABLE hardware wavetable internal synth
> + * MOD_SWSYNTH software internal synth
> + */
> +
> + /* FIXME Is this really the correct equivalence from ALSA to
> + Windows Sound type? */
> +
> + if (type & SND_SEQ_PORT_TYPE_SYNTH)
> + return MOD_FMSYNTH;
> +
> + if (type & (SND_SEQ_PORT_TYPE_DIRECT_SAMPLE|SND_SEQ_PORT_TYPE_SAMPLE))
> + return MOD_SYNTH;
> +
> + if (type & (SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION))
> + return MOD_MIDIPORT;
> +
> + ERR("Cannot determine the type (alsa type is %x) of this midi device. Assuming FM Synth\n", type);
> + return MOD_FMSYNTH;
> +}
> +
> +static void port_add(snd_seq_client_info_t* cinfo, snd_seq_port_info_t* pinfo, unsigned int cap, unsigned int type)
> +{
> + char name[MAXPNAMELEN];
> + unsigned int len;
> + struct midi_dest *dest;
> + struct midi_src *src;
> +
> + if (cap & SND_SEQ_PORT_CAP_WRITE) {
> + TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> + snd_seq_client_info_get_name(cinfo),
> + snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> + snd_seq_port_info_get_port(pinfo),
> + snd_seq_port_info_get_name(pinfo),
> + type);
> +
> + if (num_dests >= MAX_MIDIOUTDRV)
> + return;
> + if (!type)
> + return;
> +
> + dest = dests + num_dests;
> + dest->addr = *snd_seq_port_info_get_addr(pinfo);
> +
> + /* Manufac ID. We do not have access to this with soundcard.h
> + * Does not seem to be a problem, because in mmsystem.h only
> + * Microsoft's ID is listed.
> + */
> + dest->caps.wMid = 0x00FF;
> + dest->caps.wPid = 0x0001; /* FIXME Product ID */
> + /* Product Version. We simply say "1" */
> + dest->caps.vDriverVersion = 0x001;
> + /* The following are mandatory for MOD_MIDIPORT */
> + dest->caps.wChannelMask = 0xFFFF;
> + dest->caps.wVoices = 0;
> + dest->caps.wNotes = 0;
> + dest->caps.dwSupport = 0;
> +
> + /* Try to use both client and port names, if this is too long take the port name only.
> + In the second case the port name should be explicit enough due to its big size.
> + */
> + len = strlen(snd_seq_port_info_get_name(pinfo));
> + if ( (strlen(snd_seq_client_info_get_name(cinfo)) + len + 3) < sizeof(name) ) {
> + sprintf(name, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> + len = strlen(name);
> + } else {
> + len = min(len, sizeof(name) - 1);
> + memcpy(name, snd_seq_port_info_get_name(pinfo), len);
> + name[len] = '\0';
> + }
> + ntdll_umbstowcs( name, len + 1, dest->caps.szPname, ARRAY_SIZE(dest->caps.szPname));
> +
> + dest->caps.wTechnology = alsa_to_win_device_type(type);
> +
> + if (MOD_MIDIPORT != dest->caps.wTechnology) {
> + /* FIXME Do we have this information?
> + * Assuming the soundcards can handle
> + * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
> + * not MIDICAPS_CACHE.
> + */
> + dest->caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
> + dest->caps.wVoices = 16;
> +
> + /* FIXME Is it possible to know the maximum
> + * number of simultaneous notes of a soundcard ?
> + * I believe we don't have this information, but
> + * it's probably equal or more than wVoices
> + */
> + dest->caps.wNotes = 16;
> + }
> + dest->bEnabled = TRUE;
> + dest->port_out = -1;
> +
> + TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n"
> + "\tALSA info: midi dev-type=%x, capa=0\n",
> + num_dests, wine_dbgstr_w(dest->caps.szPname),
> + dest->caps.wTechnology,
> + dest->caps.wVoices, dest->caps.wNotes,
> + dest->caps.wChannelMask, dest->caps.dwSupport,
> + type);
> +
> + num_dests++;
> + }
> + if (cap & SND_SEQ_PORT_CAP_READ) {
> + TRACE("IN (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> + snd_seq_client_info_get_name(cinfo),
> + snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> + snd_seq_port_info_get_port(pinfo),
> + snd_seq_port_info_get_name(pinfo),
> + type);
> +
> + if (num_srcs >= MAX_MIDIINDRV)
> + return;
> + if (!type)
> + return;
> +
> + src = srcs + num_srcs;
> + src->addr = *snd_seq_port_info_get_addr(pinfo);
> +
> + /* Manufac ID. We do not have access to this with soundcard.h
> + * Does not seem to be a problem, because in mmsystem.h only
> + * Microsoft's ID is listed.
> + */
> + src->caps.wMid = 0x00FF;
> + src->caps.wPid = 0x0001; /* FIXME Product ID */
> + /* Product Version. We simply say "1" */
> + src->caps.vDriverVersion = 0x001;
> + src->caps.dwSupport = 0; /* mandatory with MIDIINCAPS */
> +
> + /* Try to use both client and port names, if this is too long take the port name only.
> + In the second case the port name should be explicit enough due to its big size.
> + */
> + len = strlen(snd_seq_port_info_get_name(pinfo));
> + if ( (strlen(snd_seq_client_info_get_name(cinfo)) + len + 3) < sizeof(name) ) {
> + sprintf(name, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> + len = strlen(name);
> + } else {
> + len = min(len, sizeof(name) - 1);
> + memcpy(name, snd_seq_port_info_get_name(pinfo), len);
> + name[len] = '\0';
> + }
> + ntdll_umbstowcs( name, len + 1, src->caps.szPname, ARRAY_SIZE(src->caps.szPname));
> + src->state = 0;
> +
> + TRACE("MidiIn [%d]\tname='%s' support=%d\n"
> + "\tALSA info: midi dev-type=%x, capa=0\n",
> + num_srcs, wine_dbgstr_w(src->caps.szPname), src->caps.dwSupport, type);
> +
> + num_srcs++;
> + }
> +}
> +
> +NTSTATUS midi_init(void *args)
> +{
> + struct midi_init_params *params = args;
> + static BOOL init_done;
> + snd_seq_client_info_t *cinfo;
> + snd_seq_port_info_t *pinfo;
> +
> + if (init_done) {
> + *params->err = ERROR_ALREADY_INITIALIZED;
> + return STATUS_SUCCESS;
> + }
> +
> + TRACE("Initializing the MIDI variables.\n");
> + init_done = TRUE;
> +
> + /* try to open device */
> + if (seq_open() == -1) {
> + *params->err = ERROR_OPEN_FAILED;
> + return STATUS_SUCCESS;
> + }
> +
> + cinfo = calloc( 1, snd_seq_client_info_sizeof() );
> + pinfo = calloc( 1, snd_seq_port_info_sizeof() );
> +
> + /* First, search for all internal midi devices */
> + snd_seq_client_info_set_client(cinfo, -1);
> + while (snd_seq_query_next_client(midi_seq, cinfo) >= 0) {
> + snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> + snd_seq_port_info_set_port(pinfo, -1);
> + while (snd_seq_query_next_port(midi_seq, pinfo) >= 0) {
> + unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> + unsigned int type = snd_seq_port_info_get_type(pinfo);
> + if (!(type & SND_SEQ_PORT_TYPE_PORT))
> + port_add(cinfo, pinfo, cap, type);
> + }
> + }
> +
> + /* Second, search for all external ports */
> + snd_seq_client_info_set_client(cinfo, -1);
> + while (snd_seq_query_next_client(midi_seq, cinfo) >= 0) {
> + snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> + snd_seq_port_info_set_port(pinfo, -1);
> + while (snd_seq_query_next_port(midi_seq, pinfo) >= 0) {
> + unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> + unsigned int type = snd_seq_port_info_get_type(pinfo);
> + if (type & SND_SEQ_PORT_TYPE_PORT)
> + port_add(cinfo, pinfo, cap, type);
> + }
> + }
> + seq_close();
> + free( cinfo );
> + free( pinfo );
> +
> + *params->err = NOERROR;
> + params->num_dests = num_dests;
> + params->num_srcs = num_srcs;
> + params->dests = dests;
> + params->srcs = srcs;
> +
> + TRACE("End\n");
> +
> + return STATUS_SUCCESS;
> +}
> diff --git a/dlls/winealsa.drv/midi.c b/dlls/winealsa.drv/midi.c
> index dff77ce88d8..988429ab934 100644
> --- a/dlls/winealsa.drv/midi.c
> +++ b/dlls/winealsa.drv/midi.c
> @@ -43,33 +43,12 @@
> #include "wine/debug.h"
> #include "wine/unixlib.h"
>
> -#include <alsa/asoundlib.h>
> -
> #include "unixlib.h"
>
> WINE_DEFAULT_DEBUG_CHANNEL(midi);
>
> -typedef struct {
> - int state; /* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
> - MIDIOPENDESC midiDesc;
> - WORD wFlags;
> - LPMIDIHDR lpQueueHdr;
> - DWORD startTime;
> - MIDIINCAPSW caps;
> - snd_seq_addr_t addr;
> -} WINE_MIDIIN;
> -
> -typedef struct {
> - BOOL bEnabled;
> - MIDIOPENDESC midiDesc;
> - WORD wFlags;
> - MIDIOUTCAPSW caps;
> - snd_seq_addr_t addr;
> - int port_out;
> -} WINE_MIDIOUT;
> -
> -static WINE_MIDIIN MidiInDev [MAX_MIDIINDRV ];
> -static WINE_MIDIOUT MidiOutDev[MAX_MIDIOUTDRV];
> +static WINE_MIDIIN *MidiInDev;
> +static WINE_MIDIOUT *MidiOutDev;
>
> /* this is the total number of MIDI out devices found (synth and port) */
> static int MODM_NumDevs = 0;
> @@ -124,39 +103,6 @@ static void error_handler(const char* file, int line, const char* function, int
> }
> #endif
>
> -/**************************************************************************
> - * MIDI_unixToWindowsDeviceType [internal]
> - *
> - * return the Windows equivalent to a Unix Device Type
> - *
> - */
> -static int MIDI_AlsaToWindowsDeviceType(unsigned int type)
> -{
> - /* MOD_MIDIPORT output port
> - * MOD_SYNTH generic internal synth
> - * MOD_SQSYNTH square wave internal synth
> - * MOD_FMSYNTH FM internal synth
> - * MOD_MAPPER MIDI mapper
> - * MOD_WAVETABLE hardware wavetable internal synth
> - * MOD_SWSYNTH software internal synth
> - */
> -
> - /* FIXME Is this really the correct equivalence from ALSA to
> - Windows Sound type? */
> -
> - if (type & SND_SEQ_PORT_TYPE_SYNTH)
> - return MOD_FMSYNTH;
> -
> - if (type & (SND_SEQ_PORT_TYPE_DIRECT_SAMPLE|SND_SEQ_PORT_TYPE_SAMPLE))
> - return MOD_SYNTH;
> -
> - if (type & (SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION))
> - return MOD_MIDIPORT;
> -
> - ERR("Cannot determine the type (alsa type is %x) of this midi device. Assuming FM Synth\n", type);
> - return MOD_FMSYNTH;
> -}
> -
> /**************************************************************************
> * MIDI_NotifyClient [internal]
> */
> @@ -1121,134 +1067,6 @@ static DWORD modReset(WORD wDevID)
> }
>
>
> -/**************************************************************************
> - * ALSA_AddMidiPort [internal]
> - *
> - * Helper for ALSA_MidiInit
> - */
> -static void ALSA_AddMidiPort(snd_seq_client_info_t* cinfo, snd_seq_port_info_t* pinfo, unsigned int cap, unsigned int type)
> -{
> - char midiPortName[MAXPNAMELEN];
> -
> - if (cap & SND_SEQ_PORT_CAP_WRITE) {
> - TRACE("OUT (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> - snd_seq_client_info_get_name(cinfo),
> - snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> - snd_seq_port_info_get_port(pinfo),
> - snd_seq_port_info_get_name(pinfo),
> - type);
> -
> - if (MODM_NumDevs >= MAX_MIDIOUTDRV)
> - return;
> - if (!type)
> - return;
> -
> - MidiOutDev[MODM_NumDevs].addr = *snd_seq_port_info_get_addr(pinfo);
> -
> - /* Manufac ID. We do not have access to this with soundcard.h
> - * Does not seem to be a problem, because in mmsystem.h only
> - * Microsoft's ID is listed.
> - */
> - MidiOutDev[MODM_NumDevs].caps.wMid = 0x00FF;
> - MidiOutDev[MODM_NumDevs].caps.wPid = 0x0001; /* FIXME Product ID */
> - /* Product Version. We simply say "1" */
> - MidiOutDev[MODM_NumDevs].caps.vDriverVersion = 0x001;
> - /* The following are mandatory for MOD_MIDIPORT */
> - MidiOutDev[MODM_NumDevs].caps.wChannelMask = 0xFFFF;
> - MidiOutDev[MODM_NumDevs].caps.wVoices = 0;
> - MidiOutDev[MODM_NumDevs].caps.wNotes = 0;
> - MidiOutDev[MODM_NumDevs].caps.dwSupport = 0;
> -
> - /* Try to use both client and port names, if this is too long take the port name only.
> - In the second case the port name should be explicit enough due to its big size.
> - */
> - if ( (strlen(snd_seq_client_info_get_name(cinfo)) + strlen(snd_seq_port_info_get_name(pinfo)) + 3) < MAXPNAMELEN ) {
> - sprintf(midiPortName, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> - } else {
> - lstrcpynA(midiPortName, snd_seq_port_info_get_name(pinfo), MAXPNAMELEN);
> - }
> - MultiByteToWideChar(CP_UNIXCP, 0, midiPortName, -1, MidiOutDev[MODM_NumDevs].caps.szPname,
> - ARRAY_SIZE(MidiOutDev[MODM_NumDevs].caps.szPname));
> -
> - MidiOutDev[MODM_NumDevs].caps.wTechnology = MIDI_AlsaToWindowsDeviceType(type);
> -
> - if (MOD_MIDIPORT != MidiOutDev[MODM_NumDevs].caps.wTechnology) {
> - /* FIXME Do we have this information?
> - * Assuming the soundcards can handle
> - * MIDICAPS_VOLUME and MIDICAPS_LRVOLUME but
> - * not MIDICAPS_CACHE.
> - */
> - MidiOutDev[MODM_NumDevs].caps.dwSupport = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME;
> - MidiOutDev[MODM_NumDevs].caps.wVoices = 16;
> -
> - /* FIXME Is it possible to know the maximum
> - * number of simultaneous notes of a soundcard ?
> - * I believe we don't have this information, but
> - * it's probably equal or more than wVoices
> - */
> - MidiOutDev[MODM_NumDevs].caps.wNotes = 16;
> - }
> - MidiOutDev[MODM_NumDevs].bEnabled = TRUE;
> - MidiOutDev[MODM_NumDevs].port_out = -1;
> -
> - TRACE("MidiOut[%d]\tname='%s' techn=%d voices=%d notes=%d chnMsk=%04x support=%d\n"
> - "\tALSA info: midi dev-type=%x, capa=0\n",
> - MODM_NumDevs, wine_dbgstr_w(MidiOutDev[MODM_NumDevs].caps.szPname),
> - MidiOutDev[MODM_NumDevs].caps.wTechnology,
> - MidiOutDev[MODM_NumDevs].caps.wVoices, MidiOutDev[MODM_NumDevs].caps.wNotes,
> - MidiOutDev[MODM_NumDevs].caps.wChannelMask, MidiOutDev[MODM_NumDevs].caps.dwSupport,
> - type);
> -
> - MODM_NumDevs++;
> - }
> - if (cap & SND_SEQ_PORT_CAP_READ) {
> - TRACE("IN (%d:%s:%s:%d:%s:%x)\n",snd_seq_client_info_get_client(cinfo),
> - snd_seq_client_info_get_name(cinfo),
> - snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel",
> - snd_seq_port_info_get_port(pinfo),
> - snd_seq_port_info_get_name(pinfo),
> - type);
> -
> - if (MIDM_NumDevs >= MAX_MIDIINDRV)
> - return;
> - if (!type)
> - return;
> -
> - MidiInDev[MIDM_NumDevs].addr = *snd_seq_port_info_get_addr(pinfo);
> -
> - /* Manufac ID. We do not have access to this with soundcard.h
> - * Does not seem to be a problem, because in mmsystem.h only
> - * Microsoft's ID is listed.
> - */
> - MidiInDev[MIDM_NumDevs].caps.wMid = 0x00FF;
> - MidiInDev[MIDM_NumDevs].caps.wPid = 0x0001; /* FIXME Product ID */
> - /* Product Version. We simply say "1" */
> - MidiInDev[MIDM_NumDevs].caps.vDriverVersion = 0x001;
> - MidiInDev[MIDM_NumDevs].caps.dwSupport = 0; /* mandatory with MIDIINCAPS */
> -
> - /* Try to use both client and port names, if this is too long take the port name only.
> - In the second case the port name should be explicit enough due to its big size.
> - */
> - if ( (strlen(snd_seq_client_info_get_name(cinfo)) + strlen(snd_seq_port_info_get_name(pinfo)) + 3) < MAXPNAMELEN ) {
> - sprintf(midiPortName, "%s - %s", snd_seq_client_info_get_name(cinfo), snd_seq_port_info_get_name(pinfo));
> - } else {
> - lstrcpynA(midiPortName, snd_seq_port_info_get_name(pinfo), MAXPNAMELEN);
> - }
> - MultiByteToWideChar(CP_UNIXCP, 0, midiPortName, -1, MidiInDev[MIDM_NumDevs].caps.szPname,
> - ARRAY_SIZE(MidiInDev[MIDM_NumDevs].caps.szPname));
> - MidiInDev[MIDM_NumDevs].state = 0;
> -
> - TRACE("MidiIn [%d]\tname='%s' support=%d\n"
> - "\tALSA info: midi dev-type=%x, capa=0\n",
> - MIDM_NumDevs, wine_dbgstr_w(MidiInDev[MIDM_NumDevs].caps.szPname),
> - MidiInDev[MIDM_NumDevs].caps.dwSupport,
> - type);
> -
> - MIDM_NumDevs++;
> - }
> -}
> -
> -
> /*======================================================================*
> * MIDI entry points *
> *======================================================================*/
> @@ -1260,59 +1078,19 @@ static void ALSA_AddMidiPort(snd_seq_client_info_t* cinfo, snd_seq_port_info_t*
> */
> static BOOL ALSA_MidiInit(void)
> {
> - static BOOL bInitDone = FALSE;
> - snd_seq_client_info_t *cinfo;
> - snd_seq_port_info_t *pinfo;
> -
> - if (bInitDone)
> - return TRUE;
> -
> - TRACE("Initializing the MIDI variables.\n");
> - bInitDone = TRUE;
> -
> - /* try to open device */
> - if (midiOpenSeq(FALSE) == -1) {
> - return TRUE;
> + struct midi_init_params params;
> + UINT err;
> +
> + params.err = &err;
> + ALSA_CALL(midi_init, ¶ms);
> +
> + if (!err)
> + {
> + MODM_NumDevs = params.num_dests;
> + MIDM_NumDevs = params.num_srcs;
> + MidiOutDev = params.dests;
> + MidiInDev = params.srcs;
> }
> -
> -#if 0 /* Debug purpose */
> - snd_lib_error_set_handler(error_handler);
> -#endif
> - cinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_client_info_sizeof() );
> - pinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, snd_seq_port_info_sizeof() );
> -
> - /* First, search for all internal midi devices */
> - snd_seq_client_info_set_client(cinfo, -1);
> - while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
> - snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> - snd_seq_port_info_set_port(pinfo, -1);
> - while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
> - unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> - unsigned int type = snd_seq_port_info_get_type(pinfo);
> - if (!(type & SND_SEQ_PORT_TYPE_PORT))
> - ALSA_AddMidiPort(cinfo, pinfo, cap, type);
> - }
> - }
> -
> - /* Second, search for all external ports */
> - snd_seq_client_info_set_client(cinfo, -1);
> - while(snd_seq_query_next_client(midiSeq, cinfo) >= 0) {
> - snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
> - snd_seq_port_info_set_port(pinfo, -1);
> - while (snd_seq_query_next_port(midiSeq, pinfo) >= 0) {
> - unsigned int cap = snd_seq_port_info_get_capability(pinfo);
> - unsigned int type = snd_seq_port_info_get_type(pinfo);
> - if (type & SND_SEQ_PORT_TYPE_PORT)
> - ALSA_AddMidiPort(cinfo, pinfo, cap, type);
> - }
> - }
> -
> - /* close file and exit */
> - midiCloseSeq();
> - HeapFree( GetProcessHeap(), 0, cinfo );
> - HeapFree( GetProcessHeap(), 0, pinfo );
> -
> - TRACE("End\n");
> return TRUE;
> }
>
> diff --git a/dlls/winealsa.drv/unixlib.h b/dlls/winealsa.drv/unixlib.h
> index 89afcb71bec..adac72183ee 100644
> --- a/dlls/winealsa.drv/unixlib.h
> +++ b/dlls/winealsa.drv/unixlib.h
> @@ -207,6 +207,37 @@ struct get_prop_value_params
> unsigned int *buffer_size;
> };
>
> +#include <alsa/asoundlib.h>
> +#include "mmddk.h"
> +
> +typedef struct midi_src
> +{
> + int state; /* -1 disabled, 0 is no recording started, 1 in recording, bit 2 set if in sys exclusive recording */
> + MIDIOPENDESC midiDesc;
> + WORD wFlags;
> + MIDIHDR *lpQueueHdr;
> + UINT startTime;
> + MIDIINCAPSW caps;
> + snd_seq_addr_t addr;
> +} WINE_MIDIIN;
> +
> +typedef struct midi_dest
> +{
> + BOOL bEnabled;
> + MIDIOPENDESC midiDesc;
> + WORD wFlags;
> + MIDIOUTCAPSW caps;
> + snd_seq_addr_t addr;
> + int port_out;
> +} WINE_MIDIOUT;
> +
> +struct midi_init_params
> +{
> + UINT *err;
> + unsigned int num_dests, num_srcs;
> + void *dests, *srcs;
> +};
> +
> enum alsa_funcs
> {
> alsa_get_endpoint_ids,
> @@ -232,10 +263,13 @@ enum alsa_funcs
> alsa_set_event_handle,
> alsa_is_started,
> alsa_get_prop_value,
> + alsa_midi_init,
>
> alsa_midi_seq_lock, /* temporary */
> };
>
> +NTSTATUS midi_init(void *args) DECLSPEC_HIDDEN;
> +
> NTSTATUS midi_seq_lock(void *args) DECLSPEC_HIDDEN;
>
> extern unixlib_handle_t alsa_handle;
> --
> 2.25.1
>
>
More information about the wine-devel
mailing list