mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- refactored the MIDI list code.
Let's hope nothing got broken on the Linux side, the recent submission's code was not usable.
This commit is contained in:
parent
f442d2dc54
commit
8898448014
6 changed files with 119 additions and 171 deletions
|
@ -130,21 +130,19 @@ int AlsaSequencer::EnumerateDevices() {
|
||||||
if (!filter(pinfo)) {
|
if (!filter(pinfo)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
externalDevices.emplace_back();
|
|
||||||
internalDevices.emplace_back();
|
internalDevices.emplace_back();
|
||||||
|
|
||||||
auto & item = externalDevices.back();
|
|
||||||
auto & itemInternal = internalDevices.back();
|
auto & itemInternal = internalDevices.back();
|
||||||
itemInternal.ID = item.ID = index++;
|
itemInternal.ID = index++;
|
||||||
const char *name = snd_seq_port_info_get_name(pinfo);
|
const char *name = snd_seq_port_info_get_name(pinfo);
|
||||||
int portNumber = snd_seq_port_info_get_port(pinfo);
|
int portNumber = snd_seq_port_info_get_port(pinfo);
|
||||||
if(!name) {
|
if(!name) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "MIDI Port " << clientID << ":" << portNumber;
|
out << "MIDI Port " << clientID << ":" << portNumber;
|
||||||
itemInternal.Name = item.Name = out.str();
|
itemInternal.Name = out.str();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
itemInternal.Name = item.Name = name;
|
itemInternal.Name = name;
|
||||||
}
|
}
|
||||||
itemInternal.ClientID = clientID;
|
itemInternal.ClientID = clientID;
|
||||||
itemInternal.PortNumber = portNumber;
|
itemInternal.PortNumber = portNumber;
|
||||||
|
@ -159,8 +157,4 @@ const std::vector<MidiOutDeviceInternal> & AlsaSequencer::GetInternalDevices()
|
||||||
return internalDevices;
|
return internalDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<MidiOutDevice> & AlsaSequencer::GetDevices() {
|
|
||||||
return externalDevices;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -65,7 +65,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
int EnumerateDevices();
|
int EnumerateDevices();
|
||||||
const std::vector<MidiOutDevice> &GetDevices();
|
|
||||||
const std::vector<MidiOutDeviceInternal> &GetInternalDevices();
|
const std::vector<MidiOutDeviceInternal> &GetInternalDevices();
|
||||||
|
|
||||||
snd_seq_t *handle = nullptr;
|
snd_seq_t *handle = nullptr;
|
||||||
|
@ -75,7 +74,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MidiOutDeviceInternal> internalDevices;
|
std::vector<MidiOutDeviceInternal> internalDevices;
|
||||||
std::vector<MidiOutDevice> externalDevices;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,11 @@
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
#endif
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "timidity/timidity.h"
|
#include "timidity/timidity.h"
|
||||||
#include "timiditypp/timidity.h"
|
#include "timiditypp/timidity.h"
|
||||||
|
@ -140,22 +145,85 @@ int ZMusic_EnumerateMidiDevices()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
const std::vector<MidiOutDevice> &ZMusic_GetMidiDevices()
|
struct MidiDeviceList
|
||||||
{
|
{
|
||||||
|
std::vector<MidiOutDevice> devices;
|
||||||
|
~MidiDeviceList()
|
||||||
|
{
|
||||||
|
for (auto& device : devices)
|
||||||
|
{
|
||||||
|
free(device.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Build()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPN
|
||||||
|
devices.push_back({ strdup("libOPN"), -8, MIDIDEV_FMSYNTH });
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ADL
|
||||||
|
devices.push_back({ strdup("libADL"), -7, MIDIDEV_FMSYNTH });
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WILDMIDI
|
||||||
|
devices.push_back({ strdup("WildMidi"), -6, MIDIDEV_SWSYNTH });
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
|
devices.push_back({ strdup("FluidSynth"), -5, MIDIDEV_SWSYNTH });
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GUS
|
||||||
|
devices.push_back({ strdup("GUS Emulation"), -4, MIDIDEV_SWSYNTH });
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_OPL
|
||||||
|
devices.push_back({ strdup("OPL Synth Emulation"), -3, MIDIDEV_FMSYNTH });
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TIMIDITY
|
||||||
|
devices.push_back({ strdup("TiMidity++"), -2, MIDIDEV_SWSYNTH });
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEM_MIDI
|
#ifdef HAVE_SYSTEM_MIDI
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
auto & sequencer = AlsaSequencer::Get();
|
auto& sequencer = AlsaSequencer::Get();
|
||||||
return sequencer.GetDevices();
|
auto& dev = sequencer.GetDevices();
|
||||||
#elif _WIN32
|
for (auto& d : dev)
|
||||||
// TODO: move the weird stuff from music_midi_base.cpp here, or at least to this lib and call it here
|
{
|
||||||
return {};
|
MidiOutDevice mdev = { strdup(d.Name.c_str()), d.ID, MIDIDEV_MAPPER }; // fixme: Correctly determine the type of the device.
|
||||||
#endif
|
devices.push_back(mdev);
|
||||||
#else
|
}
|
||||||
return {};
|
#elif _WIN32
|
||||||
|
UINT nummididevices = midiOutGetNumDevs();
|
||||||
|
for (uint32_t id = 0; id < nummididevices; ++id)
|
||||||
|
{
|
||||||
|
MIDIOUTCAPSW caps;
|
||||||
|
MMRESULT res;
|
||||||
|
|
||||||
|
res = midiOutGetDevCapsW(id, &caps, sizeof(caps));
|
||||||
|
if (res == MMSYSERR_NOERROR)
|
||||||
|
{
|
||||||
|
auto len = wcslen(caps.szPname);
|
||||||
|
int size_needed = WideCharToMultiByte(CP_UTF8, 0, caps.szPname, (int)len, nullptr, 0, nullptr, nullptr);
|
||||||
|
char* outbuf = (char*)malloc(size_needed + 1);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, caps.szPname, (int)len, outbuf, size_needed, nullptr, nullptr);
|
||||||
|
outbuf[size_needed] = 0;
|
||||||
|
|
||||||
|
MidiOutDevice mdev = { outbuf, id, caps.wTechnology };
|
||||||
|
devices.push_back(mdev);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static MidiDeviceList devlist;
|
||||||
|
|
||||||
|
DLL_EXPORT const MidiOutDevice* ZMusic_GetMidiDevices(int* pAmount)
|
||||||
|
{
|
||||||
|
if (devlist.devices.size() == 0) devlist.Build();
|
||||||
|
if (pAmount) *pAmount = (int)devlist.devices.size();
|
||||||
|
return devlist.devices.data();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
template<class valtype>
|
template<class valtype>
|
||||||
|
|
|
@ -189,6 +189,13 @@ struct ZMusicCustomReader
|
||||||
void (*close)(struct ZMusicCustomReader* handle);
|
void (*close)(struct ZMusicCustomReader* handle);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MidiOutDevice
|
||||||
|
{
|
||||||
|
char *Name;
|
||||||
|
int ID;
|
||||||
|
int Technology;
|
||||||
|
};
|
||||||
|
|
||||||
struct Callbacks
|
struct Callbacks
|
||||||
{
|
{
|
||||||
// Callbacks the client can install to capture messages from the backends
|
// Callbacks the client can install to capture messages from the backends
|
||||||
|
@ -288,7 +295,7 @@ extern "C"
|
||||||
DLL_IMPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, bool* startass, uint32_t* end, bool* endass);
|
DLL_IMPORT void FindLoopTags(const uint8_t* data, size_t size, uint32_t* start, bool* startass, uint32_t* end, bool* endass);
|
||||||
// The rest of the decoder interface is only useful for streaming music.
|
// The rest of the decoder interface is only useful for streaming music.
|
||||||
|
|
||||||
|
DLL_IMPORT const MidiOutDevice *ZMusic_GetMidiDevices(int *pAmount);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,6 @@ int nomusic = 0;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
void I_InitMusicWin32();
|
|
||||||
|
|
||||||
#include "musicformats/win32/i_cd.h"
|
#include "musicformats/win32/i_cd.h"
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -274,12 +272,6 @@ void I_InitMusic (void)
|
||||||
|
|
||||||
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
|
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
|
||||||
|
|
||||||
// TODO: remove, move functionality to ZMusic_EnumerateMidiDevices
|
|
||||||
#ifdef _WIN32
|
|
||||||
I_InitMusicWin32 ();
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
//ZMusic_EnumerateMidiDevices();
|
|
||||||
snd_mididevice.Callback();
|
snd_mididevice.Callback();
|
||||||
|
|
||||||
Callbacks callbacks{};
|
Callbacks callbacks{};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
**
|
**
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
** Copyright 1998-2010 Randy Heit
|
** Copyright 1998-2010 Randy Heit
|
||||||
|
** Copyright 2005-2020 Christoph Oelckers
|
||||||
** All rights reserved.
|
** All rights reserved.
|
||||||
**
|
**
|
||||||
** Redistribution and use in source and binary forms, with or without
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -31,13 +32,6 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
#include <mmsystem.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
|
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
@ -48,54 +42,17 @@
|
||||||
#define DEF_MIDIDEV -5
|
#define DEF_MIDIDEV -5
|
||||||
|
|
||||||
EXTERN_CVAR(Int, snd_mididevice)
|
EXTERN_CVAR(Int, snd_mididevice)
|
||||||
static uint32_t nummididevices;
|
|
||||||
|
|
||||||
#define NUM_DEF_DEVICES 7
|
void I_BuildMIDIMenuList(FOptionValues* opt)
|
||||||
|
|
||||||
static void AddDefaultMidiDevices(FOptionValues *opt)
|
|
||||||
{
|
{
|
||||||
FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(NUM_DEF_DEVICES)];
|
int amount;
|
||||||
pair[0].Text = "FluidSynth";
|
auto list = ZMusic_GetMidiDevices(&amount);
|
||||||
pair[0].Value = -5.0;
|
|
||||||
pair[1].Text = "TiMidity++";
|
|
||||||
pair[1].Value = -2.0;
|
|
||||||
pair[2].Text = "WildMidi";
|
|
||||||
pair[2].Value = -6.0;
|
|
||||||
pair[3].Text = "GUS";
|
|
||||||
pair[3].Value = -4.0;
|
|
||||||
pair[4].Text = "OPL Synth Emulation";
|
|
||||||
pair[4].Value = -3.0;
|
|
||||||
pair[5].Text = "libADL";
|
|
||||||
pair[5].Value = -7.0;
|
|
||||||
pair[6].Text = "libOPN";
|
|
||||||
pair[6].Value = -8.0;
|
|
||||||
|
|
||||||
}
|
for (int i = 0; i < amount; i++)
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
void I_InitMusicWin32 ()
|
|
||||||
{
|
|
||||||
nummididevices = midiOutGetNumDevs ();
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
|
||||||
{
|
|
||||||
AddDefaultMidiDevices(opt);
|
|
||||||
|
|
||||||
for (uint32_t id = 0; id < nummididevices; ++id)
|
|
||||||
{
|
{
|
||||||
MIDIOUTCAPS caps;
|
FOptionValues::Pair* pair = &opt->mValues[opt->mValues.Reserve(1)];
|
||||||
MMRESULT res;
|
pair->Text = list[i].Name;
|
||||||
|
pair->Value = (float)list[i].ID;
|
||||||
res = midiOutGetDevCaps (id, &caps, sizeof(caps));
|
|
||||||
assert(res == MMSYSERR_NOERROR);
|
|
||||||
if (res == MMSYSERR_NOERROR)
|
|
||||||
{
|
|
||||||
FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(1)];
|
|
||||||
pair->Text = caps.szPname;
|
|
||||||
pair->Value = (float)id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,112 +73,44 @@ static void PrintMidiDevice (int id, const char *name, uint16_t tech, uint32_t s
|
||||||
case MIDIDEV_WAVETABLE: Printf ("WAVETABLE"); break;
|
case MIDIDEV_WAVETABLE: Printf ("WAVETABLE"); break;
|
||||||
case MIDIDEV_SWSYNTH: Printf ("SWSYNTH"); break;
|
case MIDIDEV_SWSYNTH: Printf ("SWSYNTH"); break;
|
||||||
}
|
}
|
||||||
if (support & MIDICAPS_CACHE)
|
|
||||||
{
|
|
||||||
Printf (" CACHE");
|
|
||||||
}
|
|
||||||
if (support & MIDICAPS_LRVOLUME)
|
|
||||||
{
|
|
||||||
Printf (" LRVOLUME");
|
|
||||||
}
|
|
||||||
if (support & MIDICAPS_STREAM)
|
|
||||||
{
|
|
||||||
Printf (" STREAM");
|
|
||||||
}
|
|
||||||
if (support & MIDICAPS_VOLUME)
|
|
||||||
{
|
|
||||||
Printf (" VOLUME");
|
|
||||||
}
|
|
||||||
Printf (TEXTCOLOR_NORMAL "\n");
|
Printf (TEXTCOLOR_NORMAL "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMD (snd_listmididevices)
|
CCMD (snd_listmididevices)
|
||||||
{
|
{
|
||||||
UINT id;
|
int amount;
|
||||||
MIDIOUTCAPS caps;
|
auto list = ZMusic_GetMidiDevices(&amount);
|
||||||
MMRESULT res;
|
|
||||||
|
|
||||||
PrintMidiDevice(-8, "libOPN", MIDIDEV_FMSYNTH, 0);
|
for (int i = 0; i < amount; i++)
|
||||||
PrintMidiDevice(-7, "libADL", MIDIDEV_FMSYNTH, 0);
|
|
||||||
PrintMidiDevice (-6, "WildMidi", MIDIDEV_SWSYNTH, 0);
|
|
||||||
PrintMidiDevice (-5, "FluidSynth", MIDIDEV_SWSYNTH, 0);
|
|
||||||
PrintMidiDevice (-4, "Gravis Ultrasound Emulation", MIDIDEV_SWSYNTH, 0);
|
|
||||||
PrintMidiDevice (-3, "Emulated OPL FM Synth", MIDIDEV_FMSYNTH, 0);
|
|
||||||
PrintMidiDevice (-2, "TiMidity++", MIDIDEV_SWSYNTH, 0);
|
|
||||||
if (nummididevices != 0)
|
|
||||||
{
|
{
|
||||||
for (id = 0; id < nummididevices; ++id)
|
PrintMidiDevice(list[i].ID, list[i].Name, list[i].Technology, 0);
|
||||||
{
|
|
||||||
FString text;
|
|
||||||
res = midiOutGetDevCaps (id, &caps, sizeof(caps));
|
|
||||||
if (res == MMSYSERR_NODRIVER)
|
|
||||||
text = "<Driver not installed>";
|
|
||||||
else if (res == MMSYSERR_NOMEM)
|
|
||||||
text = "<No memory for description>";
|
|
||||||
else if (res == MMSYSERR_NOERROR)
|
|
||||||
text = caps.szPname;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PrintMidiDevice (id, text, caps.wTechnology, caps.dwSupport);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // _WIN32
|
|
||||||
|
|
||||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
|
||||||
{
|
|
||||||
AddDefaultMidiDevices(opt);
|
|
||||||
#if 0
|
|
||||||
auto devices = ZMusic_GetMidiDevices();
|
|
||||||
|
|
||||||
for (auto & device: devices)
|
|
||||||
{
|
|
||||||
FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(1)];
|
|
||||||
pair->Text = device.Name.c_str();
|
|
||||||
pair->Value = (float)device.ID;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
CCMD (snd_listmididevices)
|
|
||||||
{
|
|
||||||
Printf("%s-8. libOPN\n", -8 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
Printf("%s-7. libADL\n", -7 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
Printf("%s-6. WildMidi\n", -6 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
Printf("%s-5. FluidSynth\n", -5 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
Printf("%s-4. Gravis Ultrasound Emulation\n", -4 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
Printf("%s-3. Emulated OPL FM Synth\n", -3 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
Printf("%s-2. TiMidity++\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : "");
|
|
||||||
#if 0
|
|
||||||
auto devices = ZMusic_GetMidiDevices();
|
|
||||||
|
|
||||||
for (auto & device: devices)
|
|
||||||
{
|
|
||||||
Printf("%s%d. %s\n", -2 == snd_mididevice ? TEXTCOLOR_BOLD : "", device.ID, device.Name.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
CUSTOM_CVAR (Int, snd_mididevice, DEF_MIDIDEV, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||||
{
|
{
|
||||||
//auto devices = ZMusic_GetMidiDevices();
|
int amount;
|
||||||
//if ((self >= (signed)devices.size()) || (self < -8))
|
auto list = ZMusic_GetMidiDevices(&amount);
|
||||||
if ((self >= (signed)nummididevices) || (self < -8))
|
|
||||||
|
bool found = false;
|
||||||
|
// The list is not necessarily contiguous so we need to check each entry.
|
||||||
|
for (int i = 0; i < amount; i++)
|
||||||
|
{
|
||||||
|
if (self == list[i].ID)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
{
|
{
|
||||||
// Don't do repeated message spam if there is no valid device.
|
// Don't do repeated message spam if there is no valid device.
|
||||||
if (self != 0)
|
if (self != 0 && self != -1)
|
||||||
{
|
{
|
||||||
Printf("ID out of range. Using default device.\n");
|
Printf("ID out of range. Using default device.\n");
|
||||||
}
|
}
|
||||||
self = DEF_MIDIDEV;
|
if (self != DEF_MIDIDEV) self = DEF_MIDIDEV;
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (self == -1)
|
|
||||||
{
|
|
||||||
self = DEF_MIDIDEV;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool change = ChangeMusicSetting(zmusic_snd_mididevice, nullptr, self);
|
bool change = ChangeMusicSetting(zmusic_snd_mididevice, nullptr, self);
|
||||||
|
|
Loading…
Reference in a new issue