簡體   English   中英

在Python / PyGame上的MIDI,Ubuntu 12.04

[英]MIDI on Python / PyGame, Ubuntu 12.04

試圖讓一個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一樣。

有任何想法嗎? :)

雖然這不能完全回答您的問題,但它可以幫助您自己調試問題。

錯誤是這樣的:

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找到自己的依賴libasound (不太可能)。
  • libportmidi包裝中有一個錯誤,它沒有引用libasound.so.2 這可能是特定於平台的(例如,僅64位系統上的錯誤)。

我建議您嘗試在系統中找到包含snd_seq_event_input_pending函數的庫,然后向后工作以嘗試確定它未與libportmidi鏈接的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

我有完全相同的問題(在Ubuntu 12.04.1上),使用例如Frescobaldi中的MIDI播放工具(這是一個Python應用程序)。 這曾經很好,但現在不行了。

這顯然是一個錯誤編譯的portmidi包,它在2013-01-25推出,請參閱https://launchpad.net/ubuntu/+source/portmidi/1:200-0ubuntu1.12.04.1 降級到之前的1:200-0ubuntu1包為我解決了這個問題。

我想正確的做法是在Launchpad上的https://bugs.launchpad.net/ubuntu/+source/portmidi/+bugs上針對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存儲庫中仍有不少軟件包被破壞因為那。)

如果你現在想要修復它,你可以檢查最新版本的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

您的應用現在應該有效......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM