【问题标题】:pygame.mixer.music.play() doesn't recognize Fast Tracker (.xm music format) repeat positionpygame.mixer.music.play() 无法识别 Fast Tracker(.xm 音乐格式)重复位置
【发布时间】:2018-04-17 07:13:19
【问题描述】:

问题是:

我尝试无限循环播放 Fast Tracker 模块,但这样做只是从头开始重播音乐,而不是跟随重复位置。

示例: (这是模块https://api.modarchive.org/downloads.php?moduleid=153915#zeta_force_level_2.xm的来源)

import pygame

pygame.mixer.init()
pygame.mixer.music.load('/path/to/zeta_force_level_2.xm')
pygame.mixer.music.play(-1)

我想要实现的目标: 循环播放模块音乐,每次都在重复位置循环,而不是在轨道开始处循环。没有必要使用pygame:我使用它是因为我没有找到适合播放跟踪器音乐的东西

提前致谢。

【问题讨论】:

    标签: python python-3.x pygame audio-player


    【解决方案1】:

    更新:我在 cython 中编写了一个简单的演示,可以成功播放您链接的 .xm 文件。它基本上是this c demo code 的翻译。我的代码可以在this github page 上找到。为了让它在 Ubuntu 中工作,我必须安装 libxmp-dev 包。请注意,目前所有内容都是硬编码的,因此需要对其进行重构以更直接地在您的项目中使用。


    这绝不是一个决定性的答案。在此过程中,我遇到了许多潜在的陷阱,这让我怀疑 pygame 是否适合这里的工作,但我将介绍到目前为止我发现的内容以及一些建议。

    看起来.xm Fast Tracker MODule 格式与您典型的 wav/ogg/mp3 文件不同,它不仅可以播放一组样本数据,还可以组合不同的 MIDI乐器和样本一起创造你的音乐,就像问题中链接的(甜美的)chiptune。

    事实证明,SDL/pygame 可以播放此类文件,但方式相当有限。查看pygame的music模块,有一个set_pos函数。但是,尝试使用它给了我一个pygame.error: set_pos unsupported for this codec。然而有趣的是,我可以通过使用pygame.mixer.music.play 和可选的start 关键字来解决这个问题。虽然大多数文件格式上的start 只是开始文件前几秒的偏移量(仅在歌曲的第一次播放时),但它对于MOD 文件(如问题中的.xm 文件)具有不同的含义。 Apparently,对应MOD文件中的pattern编号。因此,根据每个模式在文件中的起始位置,可以在 pygame 中使用的潜在起始点数量非常有限。

    如果您想从一个特定的模式编号开始,那么下面的代码就足以循环。请注意,我使用 pygame 的事件系统来查看声音何时完成以使用适当的“模式偏移”“循环”声音文件:

    import pygame
    
    pygame.init()
    pygame.mixer.music.load('zeta_force_level_2.xm')
    pattern = 10
    loop_event = pygame.USEREVENT + 1
    pygame.mixer.music.set_endevent(loop_event)
    pygame.mixer.music.play(start=pattern)
    
    while True:
        for event in pygame.event.get():
            if event.type == loop_event:
                pygame.mixer.music.play(start=pattern)
    

    此时,您可能想知道这些patterns 到底是什么?如果您的系统上安装了 ffmpeg,您可以在您的文件上运行 ffprobe 并获得以下输出:

    Input #0, libmodplug, from 'zeta_force_level_2.xm':
      Metadata:
        name            : zeta force level 2
        instrument      : by zabutom --
                        : bye bye computer..
                        : see you in a week
        sample          : zeta force level 2
        extra info      : 20 patterns, 10 channels, 3/14 instruments, 1/14 sample
      Duration: 00:01:01.00, bitrate: 3 kb/s
        Stream #0:0: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s
    

    该文件中似乎有 20 种模式,您可以从中选择作为循环的起始位置。要获取有关您的特定文件的更多信息,您可以在 MilkyTracker 之类的工具中打开(并编辑!)您的文件并获得如下输出:

    youtube 上有一些 MilkyTracker 的在线教程,但它看起来是一个相当复杂的软件。

    似乎还有一个名为libxmp 的库及其对应的python binding。这应该处理将 MOD 文件数据“渲染”为简单 PCM 数组所需的转换,该数组可以在 pyaudio 或任何与 OpenAL 绑定的 python 库中播放。不管怎样,看起来你的工作已经完成了!

    【讨论】:

    • libxmp-python 看起来很有趣,但我需要测试它是否正确重放。如果是,我会接受答案,无论如何谢谢你的回复。
    • @MaxLunar 我将在本周剩下的时间(再过 4 天)保持赏金开放,这将逐渐让您的问题更加清晰。考虑到未接受的问题也更有可能获得答案,我建议等待接受直到最后看看是否出现其他答案。
    • @MaxLunar 刚刚试用了我链接的库,想知道您使用的是什么操作系统平台和 python 版本?看起来 libxmp python 绑定可能是在考虑 python2 的情况下编写的......
    • @CodeSurgeon 我正在使用 python 3.5,实际上我想同时针对 Linux 和 Windows。我已经在 Win 上使用 pygame 测试了该解决方案,但似乎我搞砸了一些东西,或者它在这里不起作用(根本没有声音)。
    • @CodeSurgeon 在尝试播放跟踪器音乐时看起来也取决于系统。 Linux 也可以播放声音,但 Windows 不能。我也在努力实现可移植性,所以无论我在哪里开始我的脚本,它都应该播放声音。这有可能解决吗?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    相关资源
    最近更新 更多