adventuregamestudio / ags

AGS editor and engine source code
Other
695 stars 159 forks source link

MIDI output device not detected correctly on Linux #367

Closed berolinux closed 2 years ago

berolinux commented 7 years ago

MIDI sound doesn't work on my box because:

Trying digital driver ID: 'Auto' (0xffffffff), MIDI driver ID: 'Auto' (0xffffffff) ALSA lib rawmidi_hw.c:233:(snd_rawmidi_hw_open) open /dev/snd/midiC0D0 failed: No such file or directory

The correct device node is /dev/snd/midiC2D0 rather than C0D0 -- card 2 is the virtual MIDI adapter provided by TiMidity++. ags should try multiple cards instead of aborting if it can't find a MIDI device on card 0.

aplaymidi works with -p 128:0 -- probably the ports are the right thing to look for.

rudolfwalter commented 7 years ago

Until this gets fixed, a possible workaround might be to create an /etc/allegro.cfg file with the following contents:

[sound]
alsa_rawmidi_device = hw:2,0

(Use hw:x,y for /dev/snd/midiCxDy.)

ghost commented 7 years ago

I am not sure if this is possible to fix in AGS itself, because (unless I missed something) it is Allegro library that does the device detection, and similar low level work.

legluondunet commented 4 years ago

Same problem on Ubuntu 19.10:

$ ./startgame 
Adventure Game Studio v3.5 Interpreter
Copyright (c) 1999-2011 Chris Jones and 2011-2019 others
ACI version 3.5.0.23

Initializing allegro
Initializing game data
Located game data file: /home/legluondunet/Bureau/tmp/ags/ags_3.5.0.23_linux/data/Maniac.exe
Opened game data file: ac2game.dta
Game data version: 26
Compiled with: 2.61
Setting up game configuration
Data directory: /home/legluondunet/Bureau/tmp/ags/ags_3.5.0.23_linux/data/
Voice pack found and initialized.
Setting up window
Initializing TTF renderer
Initializing keyboard
Initializing mouse: number of buttons reported is 3
Install timer
Sound settings: digital driver ID: 'AUTO' (0xffffffff), MIDI driver ID: 'AUTO' (0xffffffff)
ALSA lib rawmidi_hw.c:233:(snd_rawmidi_hw_open) open /dev/snd/midiC0D0 failed: Aucun fichier ou dossier de ce type
Trying to init: digital driver ID: 'SDL2' (0x53444c32), MIDI driver ID: 'NONE' (0x0)
Warning: cannot enable MIDI audio.
Problem: No compatible drivers found in the system.

You may supress this message by disabling MIDI sound in the game setup.
Installed digital driver ID: 'SDL2' (0x53444c32), MIDI driver ID: 'NONE' (0x0)
Install exit handler
Initialize legacy path finder library
Game GUI version: 105
Plugin 'AGSflashlight' could not be loaded (expected 'libAGSflashlight.so'), trying built-in plugins...
Build-in plugin 'AGSflashlight' found and being used.
Game title: 'Maniac Mansion Deluxe'
Checking for disk space
Game native resolution: 320 x 200 (16 bit)
Graphic settings: driver: OGL, windowed: yes, screen def: scaling, screen size: 0 x 0, match device ratio: ignore, game scale: max_round
Running OpenGL: 4.6
Mouse control: off, base: 1,000000, speed: 1,000000
Initialize sprites
Audio is processed on the main thread
Engine initialization complete
Starting game
***** ENGINE HAS SHUTDOWN

same result if

game: Maniac Mansion Deluxe I even copied patches.dat

legluondunet commented 4 years ago

AGS finally plays midi on Ubuntu 20.04 with this version: https://github.com/adventuregamestudio/ags/issues/1062

rofl0r commented 3 years ago

it doesn't for me. i wasted about 5 hours yesterday trying to get midi to work. when midiid is set to auto, it always uses AMID which for some reason doesn't work at all - amidi -l and aconnect -l show only Virtual Raw MIDI devices and as far as i understood those don't work on their own - they need to be "connected" to some daemon, which seems to be timidity in daemon mode on most distros. but this is all utterly undocumented, even just finding out which command line option toggles daemon mode in timidity takes hours of research (and in my case it doesn't work because timidity insists on using alsa 0.9 symver symbols which my alsa doesn't support). it is the only program still using these ancient APIs. even if it was built-in, timidity would need to be set up to find midi patches, another badly documented topic. in my case i can run timidity as command line program using ao backend and configured to use an .sf2 soundfont, but not as daemon. after reading some other issues on this tracker i found out that README documents where to put and get soundpatches for allegro and somewhere was mentioned that digiid needs to be set to "DIGI", which supposedly should make allegro pick up the .pat file and playback midis using its own engine and output to the pcm driver. i managed to make it find its patches, but there's still no audio coming out of the speakers, except when a game plays a wave sound effect, which suggests that the wave/pcm driver properly works, but the digi driver somehow not. there's also zero debug output what happens so debugging this would probably require to dig into allegro sources - there's no error message whatsoever suggesting something failed.

the good news is that on SDL2 branch the midi output works by default somewhat, somewhat because it sounds heavily distorted and the ags output is spammed with DEBUG output from SDL2_sound which tries to open timidity.cfg in a hardcoded location and apparently expects it using a GUS-style config with patch names, rather than one using a soundfont. the output looks like:

WARNING: channel 2 - same clip assigned
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat
DEBUG: Couldn't open /usr/share/timidity/instruments/.pat

i tried to run ags with gdb to debug the code in question ( libmodplug/load_pat.c ) however SDL2 has this issue https://stackoverflow.com/questions/43856252/sdl2-gdb-program-received-signal-unknown-signal which prevents it from being debugged.

this is really frustrating. imo in allegro linux mode AGS should always default to DIGI driver and fail to even start if the patches file isn't found - it could even print a message where to get it.

ivan-mogilko commented 3 years ago

This is my fault that I forgot to note DIGI option for midi in general readme (OPTIONS.md).

imo in allegro linux mode AGS should always default to DIGI driver

This may be done perhaps.

and fail to even start if the patches file isn't found

But I cannot agree to this, today almost no games have midi sound, we cannot expect users are even aware that these patches are necessary.

ericoporto commented 3 years ago

@rofl0r , have you tried the newer SDL2_sound from mercurial? It has a bunch of libmodplug fixes. Just commenting because last time you mentioned you were using the older version. I don't know if this changes anything since I haven't tested MIDI games.

Sdl2 sound supports tracker formats that have their own soundfont in the song itself which I think is a better format than MIDI, and AGS also accepts these other tracker formats too, so for newer game, if someone wants to use tracker music for some reason, these should be preferred - I forgot the formats but this is mentioned in ags-manual.

rofl0r commented 3 years ago

@ericoporto yes i updated to latest "default" branch from 5 weeks ago (no changes since)

i fixed the issues i encountered in the patch attached to my bugreport: https://bugzilla.libsdl.org/show_bug.cgi?id=5464

with the above patch i finally can play my recompiled "larry 2 point & click" with music.

and fail to even start if the patches file isn't found

But I cannot agree to this, today almost no games have midi sound, we cannot expect users are even aware that these patches are necessary.

well, it could fail like "error: you have midi enabled in your config, but no pattern.dat. you need to either download them from here (link) and put them to (directoryname), or set midiid=NONE in your config, or run ags with --no-midi switch". was just an idea really.

ivan-mogilko commented 3 years ago

well, it could fail like "error: you have midi enabled in your config, but no pattern.dat. you need to either download them from here (link) and put them to (directoryname), or set midiid=NONE in your config, or run ags with --no-midi switch"

I could e.g. make it display the message and switch to NONE automatically? Current code fallbacks to "auto", if I remember correctly, so you may end up with allegro default driver.

Or we need to determine the rule for engine behavior in case it could not init a driver from config. In the past I received request from some game developers that engine should start anyway with some default settings, so I followed this guideline in past few years.

rofl0r commented 3 years ago

In the past I received request from some game developers that engine should start anyway with some default settings, so I followed this guideline in past few years.

hmm, since there's always this tradeoff between what game developers want, and what engine users want maybe it would be a good idea to have a build option like "bundled version" that does everything developers want that ship the engine together with the game, and an "unlocked" version for people that compile their ags from source or supplied with a linux distro which is meant to play all sorts of (old) games, and not just one specific title. such unlocked version could then have --debug built-in, for example. and lookup for config file and savegames etc could be according to user wishes, not developers.

ericoporto commented 3 years ago

Cool fixes @rofl0r , submitting upstream bugs and patches is the right way, it's a bit soon so I am curious to see what it gets either answered or merged.

I found a libmodplug here on GitHub with some fixes (https://github.com/sezero/libmodplug) but from reading the code nothing MIDI related - except there's a commit exactly about the hardcoded path but the person just hardcoded differently :/

(Someone reported the same distortion you mentioned here: https://love2d.org/forums/viewtopic.php?t=88707&p=233438)

(And the Path here: https://sourceforge.net/p/modplug-xmms/bugs/19/)

(Why not use MIDI at all / crossplatform problems-> https://love2d.org/forums/viewtopic.php?t=82951#p204234 )

rofl0r commented 3 years ago

I found a libmodplug here on GitHub with some fixes (https://github.com/sezero/libmodplug)

yeah, @sezero is the guy who did almost all of the recent work on SDL2-sound (and on SDL2 too, for that matter).

ericoporto commented 3 years ago

@rofl0r , your patch has been accepted and some other fixes are in too.

About the MIDI distortion, do you have any ideas on what causes it? (I am not much familiar with the MIDI format :/)

rofl0r commented 3 years ago

About the MIDI distortion, do you have any ideas on what causes it?

since the engine failed to find sound instrument patterns, and it works correctly with the bug fixed, i guess the distorted sound was caused by whatever sdl2-sound uses as a fallback.

i now use these instruments, which ship a timidity.cfg that works: https://codeberg.org/sabotage-linux/sabotage/commit/695160c1c77a70e6e59fbfdda844a23ef077e97e

the only issue still left with midi playback in sdl2 port is that every X seconds, there's like a tiny pause where note playing is delayed, it's not a huge problem but a little bit annoying none-the-less.

ericoporto commented 3 years ago

since the engine failed to find sound instrument patterns, and it works correctly with the bug fixed, i guess the distorted sound was caused by whatever sdl2-sound uses as a fallback.

I did a little looking into the code and could not figure out where such fallback would be in there. There wasn't that much code to look so I expected something more obvious but it apparently should just return a false and bail if no file was found.

the only issue still left with midi playback in sdl2 port is that every X seconds, there's like a tiny pause where note playing is delayed

This sounds like the MIDI is getting out of sync and has to catch up (in this case by delaying) or if these are in the end of a song just before the loop, then can be a silence inserted to avoid a pop when the song finishes (but could be skipped in case of looping).

rofl0r commented 3 years ago

This sounds like the MIDI is getting out of sync and has to catch up (in this case by delaying)

this could be possible, yeah

or if these are in the end of a song just before the loop, then can be a silence inserted to avoid a pop when the song finishes (but could be skipped in case of looping).

no, this happens like every 5 secs. the tune is definitely not over there.

my own suspicion is that in this scenario the pcm buffer isn't filled quickly enough due to some timing issue or a more-costly-than-usual calculation.

ericoporto commented 3 years ago

Still on the .pat and timidity topic

I discovered there is also a format for soundfonts called .sf2, maybe if libmodplug supported loading custom soundfonts this could be something. See here: https://midis.fandom.com/wiki/Category:Soundfonts

But I don't know what is the work to change the timidity loader in libmodplug to provide a .sf2 loader.

A person in the love forum said the following:

The issue is that while löve does indeed support parsing midi formats, it does so through the included libmodplug library, which expects something called Timidity to exists. Without it, it will play all notes as the same default instrument, which seems to be some simple waveform... beeps basically.

Maybe the code for these beeps generation could be adjusted to sound a bit better - like programmatically generating a soundfont in RAM.


About the other issue I don't have anything in mind yet, nothing in the code has clicked for me. Not sure even on how to report it. :/

ivan-mogilko commented 3 years ago

the only issue still left with midi playback in sdl2 port is that every X seconds, there's like a tiny pause where note playing is delayed,

I actually experience something similar or worse on Windows with SDL port, MIDI playback is distorted beyond recognition. Maybe about x5 or x10 times slower.

ericoporto commented 3 years ago

@ivan-mogilko I don't know how to set the sound font on Windows, maybe asking upstream?

rofl0r commented 3 years ago

I discovered there is also a format for soundfonts called .sf2, maybe if libmodplug supported loading custom soundfonts this could be something. See here: https://midis.fandom.com/wiki/Category:Soundfonts

yes, this is something libmodplug doesn't support - my patch actually adresses this too by printing an "info" level message that soundfonts aren't supported, if encountered in timidity.cfg.

@ivan-mogilko I don't know how to set the sound font on Windows, maybe asking upstream?

if there's something like strace for windows (i seem to recall that on nir sofer's freeware page there's a tool to log win32 API calls) one could find out if SDL2_sound tries to open a timidity config file and files, falling back to the built-in waveforms @ericoporto mentioned.

rofl0r commented 3 years ago

i seem to recall that on nir sofer's freeware page there's a tool to log win32 API calls

i didn't find that particular program anymore, albeit there's one which can log file open events, but here's a list of other general purpose API call monitoring progs for windows:

https://stackoverflow.com/questions/2825960/wanted-winapi-calls-logger

i strongly suspect SDL2_sound tries to open timidity.cfg on windows too...

ericoporto commented 3 years ago

I opened a ticket here about documentation: https://bugzilla.libsdl.org/show_bug.cgi?id=5475

I think files needs to be manually copied by hand to these directories from looking at the source code:

#define TIMIDITYCFG "C:\\TIMIDITY\\TIMIDITY.CFG"
#define PATHFORPAT  "C:\\TIMIDITY\\INSTRUMENTS"

So what files? I don't know yet, I perused a bunch of binaries of timidity but I can't seem to find instruments packed with them.

Edit: I think I found one that can be manipulated for windows here (https://youfailit.net/pub/idgames/sounds/eawpats.zip) , but it appears to have some copyright issues.

the timidity.cfg appears to be wrong, it points to the dir d:\doom\misc\patches by default, so these have to be adjusted after extracting.

Edit2:

ok, I think I managed it.

Download this file: https://drive.google.com/file/d/1LPkw9iVAxLipf0pkVvk_TS7aWTOC-AJu/view?usp=sharing

Extract it to your C: directory and it should work.

Edit3: perusing allegro4 source code I don't understand how it magically works and sounds ok in Windows without any soundfont.

Edit4: larry_midi_test.zip

Unfortunately this game in particular still sounds terrible in Windows and I can't figure out what is wrong.

Maybe if there's a way to use the midi part of allegro:

along with the rest is better, since it's onle 1600 lines of code and it works, but it should short circuit to sdl2 for rendering in some way...

ericoporto commented 3 years ago

@rofl0r the larry game attached in the previous comment, it has a .ags file and I think the MIDI is inside, can you extract it for me? I am making a minimal play_midi.c software that I can test with both sdl2_sound and allego4 midi to help me figure how this works, and could use that midi file for testing.

rofl0r commented 3 years ago

i already pointed out earlier a free patchset that i use. it also ships a timidity.cfg so it's ready to "rock".

here's the requested midi files from larry 2 point&click. mid.zip

ericoporto commented 3 years ago

Thanks for the midi files!

Edit: https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/

Found docs on the Windows MIDI api used by the Allegro midi device on Windows.

ivan-mogilko commented 2 years ago

I think I'll close this, as we "officially" moved to SDL2, so problems related to allegro4 sound output are no longer applicable (unless with the older versions); and it seems the original matter should have been addressed within allegro4 lib itself.

Meanwhile, the sdl_sound seem to technically work on linux, assuming timidity.cfg and patches are provided.

For any problems with the latest version - please open new reports.