mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 06:42:12 +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)) {
|
||||
continue;
|
||||
}
|
||||
externalDevices.emplace_back();
|
||||
internalDevices.emplace_back();
|
||||
|
||||
auto & item = externalDevices.back();
|
||||
auto & itemInternal = internalDevices.back();
|
||||
itemInternal.ID = item.ID = index++;
|
||||
itemInternal.ID = index++;
|
||||
const char *name = snd_seq_port_info_get_name(pinfo);
|
||||
int portNumber = snd_seq_port_info_get_port(pinfo);
|
||||
if(!name) {
|
||||
std::ostringstream out;
|
||||
out << "MIDI Port " << clientID << ":" << portNumber;
|
||||
itemInternal.Name = item.Name = out.str();
|
||||
itemInternal.Name = out.str();
|
||||
}
|
||||
else {
|
||||
itemInternal.Name = item.Name = name;
|
||||
itemInternal.Name = name;
|
||||
}
|
||||
itemInternal.ClientID = clientID;
|
||||
itemInternal.PortNumber = portNumber;
|
||||
|
@ -159,8 +157,4 @@ const std::vector<MidiOutDeviceInternal> & AlsaSequencer::GetInternalDevices()
|
|||
return internalDevices;
|
||||
}
|
||||
|
||||
const std::vector<MidiOutDevice> & AlsaSequencer::GetDevices() {
|
||||
return externalDevices;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,7 +65,6 @@ public:
|
|||
}
|
||||
|
||||
int EnumerateDevices();
|
||||
const std::vector<MidiOutDevice> &GetDevices();
|
||||
const std::vector<MidiOutDeviceInternal> &GetInternalDevices();
|
||||
|
||||
snd_seq_t *handle = nullptr;
|
||||
|
@ -75,7 +74,6 @@ public:
|
|||
|
||||
private:
|
||||
std::vector<MidiOutDeviceInternal> internalDevices;
|
||||
std::vector<MidiOutDevice> externalDevices;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include "timidity/timidity.h"
|
||||
#include "timiditypp/timidity.h"
|
||||
|
@ -140,22 +145,85 @@ int ZMusic_EnumerateMidiDevices()
|
|||
#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 __linux__
|
||||
auto & sequencer = AlsaSequencer::Get();
|
||||
return sequencer.GetDevices();
|
||||
#elif _WIN32
|
||||
// TODO: move the weird stuff from music_midi_base.cpp here, or at least to this lib and call it here
|
||||
return {};
|
||||
#endif
|
||||
#else
|
||||
return {};
|
||||
#ifdef __linux__
|
||||
auto& sequencer = AlsaSequencer::Get();
|
||||
auto& dev = sequencer.GetDevices();
|
||||
for (auto& d : dev)
|
||||
{
|
||||
MidiOutDevice mdev = { strdup(d.Name.c_str()), d.ID, MIDIDEV_MAPPER }; // fixme: Correctly determine the type of the device.
|
||||
devices.push_back(mdev);
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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>
|
||||
|
|
|
@ -189,6 +189,13 @@ struct ZMusicCustomReader
|
|||
void (*close)(struct ZMusicCustomReader* handle);
|
||||
};
|
||||
|
||||
struct MidiOutDevice
|
||||
{
|
||||
char *Name;
|
||||
int ID;
|
||||
int Technology;
|
||||
};
|
||||
|
||||
struct Callbacks
|
||||
{
|
||||
// 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);
|
||||
// The rest of the decoder interface is only useful for streaming music.
|
||||
|
||||
|
||||
DLL_IMPORT const MidiOutDevice *ZMusic_GetMidiDevices(int *pAmount);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -68,8 +68,6 @@ int nomusic = 0;
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
void I_InitMusicWin32();
|
||||
|
||||
#include "musicformats/win32/i_cd.h"
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -274,12 +272,6 @@ void I_InitMusic (void)
|
|||
|
||||
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();
|
||||
|
||||
Callbacks callbacks{};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2010 Randy Heit
|
||||
** Copyright 2005-2020 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** 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 "v_text.h"
|
||||
|
@ -48,54 +42,17 @@
|
|||
#define DEF_MIDIDEV -5
|
||||
|
||||
EXTERN_CVAR(Int, snd_mididevice)
|
||||
static uint32_t nummididevices;
|
||||
|
||||
#define NUM_DEF_DEVICES 7
|
||||
|
||||
static void AddDefaultMidiDevices(FOptionValues *opt)
|
||||
void I_BuildMIDIMenuList(FOptionValues* opt)
|
||||
{
|
||||
FOptionValues::Pair *pair = &opt->mValues[opt->mValues.Reserve(NUM_DEF_DEVICES)];
|
||||
pair[0].Text = "FluidSynth";
|
||||
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;
|
||||
int amount;
|
||||
auto list = ZMusic_GetMidiDevices(&amount);
|
||||
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void I_InitMusicWin32 ()
|
||||
{
|
||||
nummididevices = midiOutGetNumDevs ();
|
||||
}
|
||||
|
||||
void I_BuildMIDIMenuList (FOptionValues *opt)
|
||||
{
|
||||
AddDefaultMidiDevices(opt);
|
||||
|
||||
for (uint32_t id = 0; id < nummididevices; ++id)
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
MIDIOUTCAPS caps;
|
||||
MMRESULT res;
|
||||
|
||||
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;
|
||||
}
|
||||
FOptionValues::Pair* pair = &opt->mValues[opt->mValues.Reserve(1)];
|
||||
pair->Text = list[i].Name;
|
||||
pair->Value = (float)list[i].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_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");
|
||||
}
|
||||
|
||||
CCMD (snd_listmididevices)
|
||||
{
|
||||
UINT id;
|
||||
MIDIOUTCAPS caps;
|
||||
MMRESULT res;
|
||||
int amount;
|
||||
auto list = ZMusic_GetMidiDevices(&amount);
|
||||
|
||||
PrintMidiDevice(-8, "libOPN", MIDIDEV_FMSYNTH, 0);
|
||||
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 (int i = 0; i < amount; i++)
|
||||
{
|
||||
for (id = 0; id < nummididevices; ++id)
|
||||
{
|
||||
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);
|
||||
}
|
||||
PrintMidiDevice(list[i].ID, list[i].Name, list[i].Technology, 0);
|
||||
}
|
||||
}
|
||||
#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)
|
||||
{
|
||||
//auto devices = ZMusic_GetMidiDevices();
|
||||
//if ((self >= (signed)devices.size()) || (self < -8))
|
||||
if ((self >= (signed)nummididevices) || (self < -8))
|
||||
int amount;
|
||||
auto list = ZMusic_GetMidiDevices(&amount);
|
||||
|
||||
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.
|
||||
if (self != 0)
|
||||
if (self != 0 && self != -1)
|
||||
{
|
||||
Printf("ID out of range. Using default device.\n");
|
||||
}
|
||||
self = DEF_MIDIDEV;
|
||||
return;
|
||||
}
|
||||
else if (self == -1)
|
||||
{
|
||||
self = DEF_MIDIDEV;
|
||||
if (self != DEF_MIDIDEV) self = DEF_MIDIDEV;
|
||||
return;
|
||||
}
|
||||
bool change = ChangeMusicSetting(zmusic_snd_mididevice, nullptr, self);
|
||||
|
|
Loading…
Reference in a new issue