6

试图让 MIDI 接口在 Ubuntu 12.04 上与 pygame 一起工作。我知道键盘可以工作,因为它可以控制 vkeybd 并在 OSX 上与 PyGame 一起工作,所以 python 中的 MIDI 存在问题。

$ python -m pygame.examples.midi --list

Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/usr/lib/python2.7/dist-packages/pygame/examples/midi.py", line 820, in <module>
    print_device_info()
  File "/usr/lib/python2.7/dist-packages/pygame/examples/midi.py", line 25, in     print_device_info
    pygame.midi.init()
  File "/usr/lib/python2.7/dist-packages/pygame/midi.py", line 71, in init
    import pygame.pypm
ImportError: /usr/lib/libportmidi.so.0: undefined symbol: snd_seq_event_input_pending

python-pygame 通过包管理器安装,python-pm 也是如此。

有任何想法吗?:)

4

3 回答 3

4

虽然这不能完全回答您的问题,但它可以帮助您自己调试问题。

错误是这样的:

ImportError: /usr/lib/libportmidi.so.0: undefined symbol: snd_seq_event_input_pending

undefined symbol是动态链接器未能找到snd_seq_event_input_pending函数所需的代码。

在一个示例 32 位 Oneiric 系统上,我们可以这样做来查看libportmidi.so.0.

nm -DC /usr/lib/libportmidi.so.0 | grep snd_seq_event_input_pending

U snd_seq_event_input_pending

这告诉我们libportmidi库需要代码,snd_seq_event_input_pending但符号未定义。因此,libportmidi为了发挥作用,它还必须加载一个包含此功能的附加库。

在 Oneiric 上,我发现这个符号是在libasound2.so.2.

nm -DC /usr/lib/i386-linux-gnu/libasound.so.2 | grep snd_seq_event_input_pending

000a0fa0 T snd_seq_event_input_pending

T表示该函数存在并且在文本(代码)段中。

通常,关联库的链接会自动发生,libasound.so.2应该由libportmidi. 在同一个系统上。

ldd /usr/lib/libportmidi.so.0

....
libasound.so.2 => /usr/lib/i386-linux-gnu/libasound.so.2 (0x00e35000)

这表明libmidi取决于libasound。在ldd您的评论中的输出列表中没有对 的引用libasound,因此它不会libasound.so.2在加载时尝试自动动态链接,从而导致您的错误。

可能出现错误的原因有几个:

  • 链接方式libportmidi可能从 Oneiric 变为 Precise。例如libportmidi,可能会尝试为libasound. (不太可能)。
  • 包装中存在一个错误libportmidi,它没有libasound.so.2按应有的方式引用。这可能是特定于平台的(例如,只有 64 位系统上的错误)。

我建议您尝试找出系统上包含该snd_seq_event_input_pending函数的库,然后向后工作以尝试确定为什么它没有与libportmidi.

以下 bash 命令将帮助您找到实现snd_seq_event_input_pending. 如果您没有找到任何东西,则说明您机器上安装的库有问题。

find /lib /usr/lib -name "lib*.so.*" | while read f; do
    if nm -DC "$f" | grep -q 'T snd_seq_event_input_pending'; then
        echo "$f"
    fi
done
于 2013-01-27T05:11:31.553 回答
1

如果你想现在修复它,你可以检出最新版本的portmidi并按如下方式构建库(假设你已经检出或解压 portmidi 到一个名为 portmidi 的目录中):

cd portmidi
make -f pm_linux/Makefile 

默认安装不会构建动态版本的库,因此您需要像这样构建一个:

gcc -shared -Wl,-soname,libportmidi.so.0 -o  pm_linux/libportmidi.so.0 pm_common/pmutil.o pm_linux/pmlinuxalsa.o pm_linux/pmlinux.o pm_common/portmidi.o -lasound

然后您可以复制旧库(以防万一),然后将这个新库复制到它的位置:

sudo cp /usr/lib/libportmidi.so.0 /usr/lib/libportmidi.so.0.orig
sudo cp pm_linux/libportmidi.so.0 /usr/lib/libportmidi.so.0

您的应用程序现在应该可以运行...

于 2013-01-30T16:48:05.937 回答
1

我有完全相同的问题(在 Ubuntu 12.04.1 上),例如使用 Frescobaldi 中的 MIDI 播放工具(这是一个 Python 应用程序)。这曾经可以正常工作,但现在不行了。

这显然是一个错误编译的 portmidi 包,它于 2013 年 1 月 25 日推出,请参阅https://launchpad.net/ubuntu/+source/portmidi/1:200-0ubuntu1.12.04.1。降级到以前的 1:200-0ubuntu1 包为我解决了这个问题。

我想正确的做法是在https://bugs.launchpad.net/ubuntu/+source/portmidi/+bugs上的 Launchpad 上针对 1:200-0ubuntu1.12.04.1 版本提交错误报告。如果它没有得到修复,我们可能还会询问 falkTX,他是否愿意在他的 KXStudio PPA 中提供一个工作包。

仅作记录,以下是 ldd 为我系统上的 1:200-0ubuntu1 libportmidi 提供的内容:

linux-vdso.so.1 =>  (0x00007fffe9bff000)
libasound.so.2 => /usr/lib/x86_64-linux-gnu/libasound.so.2 (0x00007f26264cb000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f26262ae000)
libporttime.so.0 => /usr/lib/libporttime.so.0 (0x00007f26260ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2625cec000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f26259f0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f26257eb000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f26255e3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f26269f4000)

以及破碎的 1:200-0ubuntu1.12.04.1 版本:

linux-vdso.so.1 =>  (0x00007fff9e3ff000)
libporttime.so.0 => /usr/lib/libporttime.so.0 (0x00007fb84ac71000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb84a8b2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb84a694000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb84b0af000)

因此,任何没有碰巧链接到 libasound2 本身的应用程序都将被处理。具体来说,Python portmidi 模块似乎就是这种情况。(至少从 Ubuntu 12.04 开始,gcc 默认使用 --as-needed 链接器标志,这一事实也加剧了这种错误。我敢打赌,Ubuntu 存储库中仍有相当多的包被破坏正因为如此。)

于 2013-01-30T11:00:38.223 回答